DEV Community

loading...

The four pillars of OOP

paymon123 profile image Paymon Wang Lotfi Updated on ・3 min read

In such a dynamic field, it can be hard to tell what knowledge you should keep and what knowledge you might only need temporarily. Regardless of your specialization, these four established principles will appear time and time again throughout your career.

Abstraction

Handle complexity by hiding implementation details from the user. Whenever you call an API, you are using an example of abstraction. You don’t know or need to know what the code within the API looks like — you only need it to return the result. This can also apply to methods, objects, and data structures. Large-scale projects often have countless layers of abstraction, with developers working on different modules exposing complex functionality through clear and minimal public interfaces.

abstract class AlgorithmFactory{    
    //what the user of the algorithm sees
    abstract int extremelyComplexProprietaryAlgorithm(int a, int b);    
}
class AlgorithmFactoryImplementation extends AlgorithmFactory{    
    //what the writer of the algorithm sees
    int extremelyComplexProprietaryAlgorithm(int a, int b)
    {
        return a + b * a / b % b % b + a - b * b * a * b * b % a;
    }    
}
Enter fullscreen mode Exit fullscreen mode

Inheritance

Object-oriented programming attempts to model our perception of reality through relationships between entities. For example, a car is a vehicle, a truck is a vehicle, and a motorcycle is a vehicle. Therefore, the car, truck, and motorcycle classes would all inherit the vehicle class (or interface). This should not be confused with composition, which describes the has a relationship. A car has a wheel, but a wheel is not a car, and a car is not a wheel.

class Vehicle{}
class Car extends Vehicle{}
class Truck extends Vehicle{}
class Motorcycle extends Vehicle{}
Enter fullscreen mode Exit fullscreen mode

Polymorphism

This principle works closely with inheritance, and describes an object’s ability to be of more than one type of object. If you have a class car that inherits a class vehicle, a car object can be considered to be of type car and type vehicle. If you have a method that accepts a vehicle parameter, but you pass in a car parameter, runtime polymorphism will allow it to automatically be accepted as a vehicle object when it is called. There are obviously constraints and exceptions involving polymorphism, but don’t let the name intimidate you from understanding this simple concept. When you break the word down to its roots, “poly” means “many” and “morph” means “form” — polymorphism describes an object’s ability to be of multiple forms simultaneously.

class Vehicle{
    public void destroy(){System.out.println("destroying");}
}
class Car extends Vehicle{}
class Truck extends Vehicle{}
class Motorcycle extends Vehicle{}

public class PolymorphismExample
{
    public static void destroyVehicle(Vehicle v)
    {
        v.destroy();
    }
    public static void main(String[] args)
    {
        Car car = new Car();
        Truck truck = new Truck();
        Motorcycle motorcycle = new Motorcycle();
        destroyVehicle(car); //destroying
        destroyVehicle(truck); //destroying
        destroyVehicle(motorcycle); //destroying
    }
}
Enter fullscreen mode Exit fullscreen mode

Encapsulation

In object-oriented programming, it is considered standard practice to make an object’s data members private and wrap them in accessor and mutator methods. If a car object contains an integer current_gallons, you could access the value using car.current_gallons. However, if you want to prevent current_gallons from being assigned inappropriate values (such as negative numbers or strings), you would have to filter changes through getCurrentGallons() (accessor method) and setCurrentGallons() (mutator method). Even if the value has no perceivable constraints, it is still mandatory to encapsulate an object’s data members. Most IDEs have a built in function to auto-generate getters (accessors) and setters (mutators).

public class Car{
    public int current_gallons = 20; 
    public String brand = "Honda";     
}
Enter fullscreen mode Exit fullscreen mode
class Car{
    private int current_gallons = 20; 
    private String brand = "Honda";
    public void setCurrentGallons(int new_value)
    {
        if(new_value > 30 || new_value < 0)
            return;
        else
            this.current_gallons = new_value;
    }
    public int getCurrentGallons()
    {
        return current_gallons;
    }    
    public void setBrand(String new_brand)
    {
        if(new_brand.equals("") || new_brand.length() > 10)
            return;
        else
            brand = new_brand;
    }
    public String getBrand()
    {
        return brand;
    }
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)

pic
Editor guide