Progress

Pillars Of Object Oriented Programming OOPs Concept

Pillars Of Object Oriented Programming OOPs Concept

There are four main concepts which powers object oriented programming. These four pillars of object oriented programming provide a great way of writing the code.

Check the article if you want to learn object oriented programming with examples.

Let us try to understand the pillars of object oriented programming individually.

Abstraction

Abstraction is the process of showing only relevant information to the users and hiding other details of the class. The main motive of abstraction is to make classes simple because we leave out the irrelevant information.

If we zoom into the definition of abstraction, it means the user of the code has access to only required methods and attributes of the code. The user does not need to know all the details of how the operation is performed.

In simple words, we can also define it as “it hides the complexity of a class”. It focuses on ‘idea’ instead of ‘actual working’.

Example:

When we see a car, it has an abstraction layer above it which prevents us to see and interact with its complex components such as the engine.

I found One more example while exploring about abstraction which I think is worth mentioning here.

If we create a class Car which has a method move. The user knows that it will move the car but don’t that how the car will move, either by wheels or it will fly in the air ( I have seen flying cars in fast and furious movie :).

Object oriented Programming Abstraction view of a car

Encapsulation

Encapsulation means wrapping attributes (data members) and methods inside a class. It helps to prevent misuse of both attributes and methods outside of class.

It hides the internal working of the class. The users have access to the attributes and methods and they know what is their use. However, they don’t need to know how the task is performed.

The keyword ‘private’ is used to encapsulate attributes and methods of the class, however some object oriented programming languages like python and javascript don’t support them.

Encapsulation can be achieved in python in other ways but they are not that effective.

Encapsulation acts as a protective shield to prevent outside access to the class data. The example below will explain this in detail.

Why Encapsulation is important?

Suppose a scenario where we create a package which gains the community attention and thousands of developers start using that. After a certain time, you realize that certain features are causing any bug and it needs to be fixed. If you had exposed any variables or methods to be directly accessed that was not meant to be, then changing the code will break the functionality of many codes that were dependent on that.

In this case, we can only expose needed attributes and methods and provide an abstraction to all others. While fixing the bug, we only need to make sure that those exposed attributes and methods remain unchanged. It provides security as well as better handling of the code.

Abstraction and Encapsulation are very Closely related to each other with some minor differences between them.

If we take example of the car, we know that the accelerator will increase the speed and brakes will stop it. In this case, we know what they do but we don’t need to know how it is performed internally in the engine part. If the manufacturer changes the way of engine working the users will have no effect of that. They don’t even need to know about that.

Inheritance

Inheritance is the ability to create a new class with the use of available classes by inheriting their methods and attributes as suitable.

The new class inherits the methods and attributes of its parent class and uses them. Using inheritance effectively in object oriented programming helps to write code that follows DRY principal.

Example:

A parent class Account which contains all properties of a general Account, like name, email and password are there. This class will have methods like ‘login’, ‘welcome’ etc which are common to each Account.

Two other class namely UserAccount and AdminAccount inherits from Account class.

Both the classes can inherit from Account class because they both need properties and methods of that class. Both of them will definitely have their own custom attributes and methods but the common things in both implemented only once.

public class Main {
    public static void main(String[] args) {
        UserAccount user = new UserAccount();
        user.signup("User1", "[email protected]", "[email protected]#");
        // The user.login() method is inherited from parent class (Account)
        user.login("[email protected]", "[email protected]#");
        user.welcome();

        AdminAccount admin = new AdminAccount();
        admin.signup("admin1", "[email protected]", "[email protected]#");
        admin.login("[email protected]", "[email protected]#");
        // Welcome method is override in AdminAccount class itself
        // so it will be executed instead of parent class method welcome
        admin.welcome();
    }
}


class Account{

    private String name, email, password;

    public void login(String email, String password){
        System.out.println("Logging in with Email and Password");
    }

    public void welcome(){
        System.out.println("Welcome to our System User");
    }

}

//Ordinary User Account
class UserAccount extends Account{
    //Signup method is overloaded in case user want to signup with or without name.
    public void signup(String name, String email, String passowrd){
        System.out.println("Signing In The user with Name, email and Password");
    }
    public void signup(String email, String passowrd){
        System.out.println("Signing In The user with email and Password only");
    }
    public void playMusic(){
        System.out.println("Playing music for user .....");
    }
}

//Admin Account
class AdminAccount extends Account{
    public void signup(String name, String email, String passowrd){
        System.out.println("Signing In The user with Name, email and Password");
    }

    public void ModifyUserData(String email){
        System.out.println("User data with email "+email+" modified.");
    }

    @Override
    public void welcome() {
        System.out.println(" Welcome Admin. With Great power comes Great Responsibility.");
    }
}


//Output:
//        Signing In The user with Name, email and Password
//        Logging in with Email and Password
//        Welcome to our System User
//        Signing In The user with Name, email and Password
//        Logging in with Email and Password
//        Welcome Admin. With Great power comes Great Responsibility.

In the above example, UserAccount and AdminAccount inherit the data members along with login and welcome method.

Polymorphism

The concept of Polymorphism refers to an object which acts differently in different situations.

We can understand it from a class which inherit any method from its parent class but that method is again implemented in the same class, with different behaviour.

The subclass can define its own unique ways to work on some methods without affecting the inheritance of other methods with parent class.

There are two types of Polymorphism :

Runtime Polymorphism or Dynamic Polymorphism

It means resolving method overriding at runtime. When the parent class have any method which we override (implemented again) in the child class, then the child class method will be resolved at runtime and compiler will execute that.

There is a ‘Method Resolution order’ concept in python which also defines the same. The compiler/Interpreter first tries to find the method in the instantiated class, if not found there it tries to find it in a higher level of parent classes hierarchy. If found nowhere, yields an error.

Compile-time Polymorphism or Static Polymorphism

It means method overloading. Multiple methods with the same name but with a different number of parameters or types are in the class. Method resolution is on compile-time based on the number of parameters or their types.

Example :

Take our previous example with only important parts to understand this concept.

class Account{

    public void login(String email, String password){
        System.out.println("Logging in with Email and Password");
    }

    public void welcome(){
        System.out.println("Welcome to our System User");
    }

}

//Ordinary User Account
class UserAccount extends Account{
    //Signup method is overloaded in case user want to signup with or without name.
    public void signup(String name, String email, String passowrd){
        System.out.println("Signing In The user with Name, email and Password");
    }
    public void signup(String email, String passowrd){
        System.out.println("Signing In The user with email and Password only");
    }
    public void playMusic(){
        System.out.println("Playing music for user .....");
    }
}

//Admin Account
class AdminAccount extends Account{
    public void signup(String name, String email, String passowrd){
        System.out.println("Signing In The user with Name, email and Password");
    }

    public void ModifyUserData(String email){
        System.out.println("User data with email "+email+" modified.");
    }

    @Override
    public void welcome() {
        System.out.println(" Welcome Admin. With Great power comes Great Responsibility.");
    }
}

In the example, We can see that the signup method is overloaded with the same name but different types of parameters.

In AdminAccount class the welcome method is overridden from the parent class (Account), now if the welcome method is called on this class then it will execute the method of AdminAccount class instead of its parent class.

Share the Post ;)

Related Posts