DEV Community

Mohmed Ishak
Mohmed Ishak

Posted on

4 Pillars Of Object-Oriented Programming (Made Easy)

Hey guys! OOP really isn't scary at all. In this article, I'll explain the 4 pillars of object-oriented programming or OOP without lengthy explanation. The code snippets will be in Java (don't worry C# fans, they're both the same language pretty much).

[1] Encapsulation

A lot of people mix up encapsulation and abstraction, but these two are different. Encapsulation is the method of encapsulating data and methods (that use that data) in a single unit.

public class Whatever {
    public int salary = 0;

    public int getSalary() {
        return salary;
    }
}
Enter fullscreen mode Exit fullscreen mode

This is encapsulation because we're grouping together data (salary) as well as method that use that data (getSalary()) inside a class.

[2] Abstraction

To understand this, you need to understand the English word "abstraction", and that pretty much means hiding or something similar. Therefore, in OOP, abstraction means hiding the complexity and exposing only what's necessary. Now, I'll use the previous code snippet and add abstraction to it.

public class Whatever {
    private int salary = 0;

    public int getSalary() {
        return salary;
    }
}
Enter fullscreen mode Exit fullscreen mode

Here, the difference is that salary field is made private, which means no objects can change the data. However, for whatever reason we want this salary to be read by any objects so the getSalary() method remains public and can be called by any objects. Basically, we're hiding the field because we don't want any objects to modify this salary in this case.

[3] Inheritance

If a class has some implementation which is used by another class too, we've got some duplication over here. A quick fix to avoid this is to send the code up to a parent class and then both these classes will extend to the parent class and get the same implementation (except that there's no code repetition).

First let's take a look at an implementation without inheritance:

public class Student {
    public void login() {
        // ...
    }

    public void getMarks() {
        // ...
    }
}

public class Teacher {
    public void login() {
        // ...
    }

    public void setMarks(int marks) {
        // ...
    }
}
Enter fullscreen mode Exit fullscreen mode

Here, the problem is we've repeated some common codes between these two classes. It would be better if the common codes are present in a single place and these classes "connect" to the single place and yes it's possible with inheritance. Here's how inheritance can make the codebase simpler:

public class User {
    public void login() {
        // ...
    }
}

public class Student extends User {
    public void getMarks() {
        // ...
    }
}

public class Teacher extends User {
    public void setMarks(int marks) {
        // ...
    }
}
Enter fullscreen mode Exit fullscreen mode

This is much more cleaner. A student can getMarks(), while a teacher can setMarks(), and both of them can login(). No code repetition. With that said, inheritance (especially more than 1 level of inheritance) is bad as it sort of "disconnects" the mind of developers and might confuse them. Basically, the code will be harder to grasp. Use inheritance up to 1 or 2 levels only and when it wouldn't confuse anyone.

[4] Polymorphism

Poly means many, morph means forms, and -ism is probably an English suffix to make words sound good. Polymorphism means that an object can take many forms. Consider the following code:

public class User {
    // ...
}

public class Student extends User {
    public void saySomething() {
        System.out.println("I am a student");   
    }
} 

public class Teacher extends User {
    public void saySomething() {
        System.out.println("I am a student");   
    }
}

public class LabAssistant extends User {
    public void saySomething() {
        System.out.println("I am a lab assistant");   
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, I'll create three distinct objects (which all have the saySomething() method with own implementation) and store them in an array:

public class Main {
    public static void main(String[] args) {
        User[] objects = { new Student(), new Teacher(), new LabAssistant() };

        for (var obj : objects)
            obj.saySomething();
    }
}
Enter fullscreen mode Exit fullscreen mode

In this case, we're looping over an array of different objects and then invoking saySomething() method. For element one, the object will invoke saySomething() in Student class, for element two, the object will invoke saySomething() in Teacher class, and so on. See? This object just took many forms, a.k.a polymorphism.

Top comments (4)

Collapse
 
drnovikov profile image
Aleksei Novikov

I believe abstraction is not hiding information. Hiding information is "data hiding".

Abstraction is not taking away or restricting something. It is, I believe, the opposite: giving you something extra on a higher level.

Abstraction is not about taking away the access to private data and methods. Abstraction is about making it unnecessary to access these things.

Abstraction is what lets you interact with a complex system as a whole, through a simple interface.

Consider a car. You don't need to manually pump fuel from the fuel tank, inject fuel into cylinders, compress them, then electrify spark plugs, then open valves and vent out the combustion products while simultaneously pumping coolant through pipes and radiator and spinning the propeller in front of the radiator. In theory, you could do it. But usually you just press a pedal to accelerate.

The pedal is the interface, and the "car accelerator" is the abstraction which allows you to not even need to access the machinery under the hood.

Abstraction does 2 useful things:

  1. It allows to not depend on knowledge of inner workings.
  2. It allows to change the underlying machinery without user even knowing about it.

Abstraction isolates users from complexity and from changes.

I.e. an electric car has the same accelerator pedal. You press it -- the car goes faster. Same interface, same abstract idea, different machinery.

Now, the hood is "hiding". It is what prevents external things from interfering with how the car works. It is the word "private". It is something that disallows someone to cut the fuel line or inject water instead of gasoline.

Collapse
 
ishakmohmed profile image
Mohmed Ishak

Cool insight.

Collapse
 
phantas0s profile image
Matthieu Cneude

Some advice (only my opinion, of course):

  1. Abstraction is not only for OOP. You can abstract away details nobody cares in most programming languages. My take: thevaluable.dev/abstraction-type-s...
  2. Inheritance as you describe it should be rarely used, and especially not to share code as you do in your example. Otherwise, it will be difficult to modify one of your children without modifying the parent... it makes everything tightly coupled, which is often not what you want. I've written about that here: thevaluable.dev/guide-inheritance-...
  3. It's safer to use interface constructs to achieve polymorphism. Again, using inheritance here makes everything highly coupled.
  4. Many functional languages implement different ways to achieve polymorphism too...
Collapse
 
ishakmohmed profile image
Mohmed Ishak

Thanks for the knowledge man.