DEV Community

Discussion on: OOPs Concepts in TypeScript. What is the 4, Basics of Object-Oriented Programming Fundamentals & their Examples

Collapse
 
loucyx profile image
Info Comment hidden by post author - thread only visible in this permalink
Lou Cyx • Edited

Is a pretty common misconception to include inheritance and classes as part of OOP, but they aren't actually part of it.

The pioneer of OOP, Alan Kay, when talking about the meaning of OOP, said:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.

So the actual basic ingredients of OOP are:

  • Message passing.
  • Encapsulation.
  • Dynamic binding.

You might notice that "inheritance" and classes are not considered essential. Classes are just one way of doing encapsulation, but JavaScript (and by consequence TypeScript) has other ways of achieving encapsulation that are more flexible and composable than classes, namely functions, closures and modules.

Not only that, you also used the abstract keyword to give an example of the concept of "abstraction", when that concept has nothing to do with keywords. Is like saying that the definition of "math" is the + operator.

If you're wondering how your encapsulation would look like without class:

const createCustomer = () => {
    const customer: {
        name?: string;
        surname?: string;
    } = {};

    return {
        getFullName: () => `${customer.name} - ${customer.surname}`,
        setNames: (name: string, surname: string) => {
            customer.name = name;
            customer.surname = surname;
        },
    };
};

const customer = createCustomer();
customer.setNames("John", "Doe");
customer.getFullName(); // "John - Doe"
Enter fullscreen mode Exit fullscreen mode

Tho is worth mentioning that for something like this, is way better to make it more functional:

type FullName = {
    name: string;
    surname: string;
};

const fullNameToString = ({ name, surname }: FullName) => `${name} ${surname}`;

const updateFullName =
    (update: Partial<FullName>) =>
    <WithFullName extends FullName>(
        withFullName: WithFullName,
    ): WithFullName => ({
        ...withFullName,
        ...update,
    });

const customer = {
    name: "John",
    surname: "Doe",
} as const;

fullNameToString(customer); // "John Doe"
fullNameToString(updateFullName({ name: "Jane" })(customer)); // "Jane Doe"
Enter fullscreen mode Exit fullscreen mode

Now instead of having methods locked inside a Customer class, we have utils that we can reuse with anything that has FullName on it.

Cheers!

Collapse
 
loucyx profile image
Lou Cyx • Edited

Why did you hid my comment @reaganscofield ? ... I wasn't being offensive or anything like that, I just added some clarity to your post :/

Some comments have been hidden by the post's author - find out more