Four pillar of OOP in Java

Four pillar of OOP in Java

Introduction to Object Oriented Programming

Object-oriented programming is a fundamental programming concept. It is a programming style that organizes software design (code) based on classes and objects, focusing on data rather than functions or logic.

OOP was initially introduced to remove shortcomings of the procedural programming approach (used in older programming languages such as C, Fortran, and Pascal). Being data-centric rather than logic-centric allows OOP to be more organized and far more suitable for large-scale projects. As a result, the OOP approach is widely used in many modern languages including Java.

Object-oriented programming in Java revolves around four main pillars, which are Encapsulation, Abstraction, Inheritance, and Polymorphism. These four concepts are crucial for understanding and implementing OOP in Java, with each pillar serving a unique purpose in software design.

Now, let's discuss these four pillars of OOP in Java in brief.

Encapsulation

Encapsulation involves wrapping up the implementation and data members inside a class. It's a way to hide data and the code associated with it into a single unit or entity so that it can be protected from outside interference. This practice helps ensure the integrity and security of the data within the class, preventing unauthorized access and modification.

In essence, encapsulation is about containing the information within a class, making it an essential aspect of data security. It's worth noting that encapsulation is a sub-process of data hiding, as it not only hides data but also hides the complexity of the program's implementation.

public class Student {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        if (age >= 0) {
            this.age = age;
        }
    }

    public int getAge() {
        return age;
    }
}

In this example, the Student class encapsulates the name and age attributes, providing getter and setter methods to control access to these attributes. Furthermore, the private keyword ensures that these attributes cannot be accessed directly from outside the class, maintaining data integrity and security.

Abstraction

Abstraction, on the other hand, focuses on hiding unnecessary implementation details and only exposing valuable information to the user. It is a design-level concept that allows developers to simplify the complexity of their code.

Through abstraction, programmers can create a simplified model of an object or process, focusing only on the essential features and interactions, while abstracting away the intricate implementation details. This makes it easier to manage and understand complex systems, as users can interact with high-level abstractions without needing to delve into the inner workings.

List<String> myList = new ArrayList<>();
myList.add("Item 1");
myList.add("Item 2");

In this example, users work with the high-level List interface, which abstracts the underlying complexities of the ArrayList implementation. Users don't need to know how ArrayList manages memory or handles resizing; they interact with the List in a simplified way.

Polymorphism

Polymorphism is derived from two words: 'Poly,' meaning many, and 'morphism,' meaning ways to represent. In simple terms, polymorphism refers to the ability of a single entity or item to take on multiple forms or representations. It allows different objects to respond to the same method or message in different ways based on their specific implementations.

This concept enhances code reusability, simplifies system design, and promotes extensibility. Polymorphism has two main types: compile-time (method overloading) and runtime (method overriding) polymorphism. Method overloading involves defining multiple methods in the same class with different parameters, while method overriding occurs when a subclass provides a specific implementation for a method already defined in its superclass.

The concept of polymorphism is instrumental in creating adaptable and efficient software systems, making it a key technique in object-oriented programming.

class Shape {
    void draw() {
        System.out.println("Drawing a shape");
    }
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a rectangle");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape1 = new Circle();
        Shape shape2 = new Rectangle();

        shape1.draw(); // Calls Circle's draw method
        shape2.draw(); // Calls Rectangle's draw method
    }
}

In this example, shape1 and shape2 are both of type Shape, but they refer to instances of Circle and Rectangle. When the draw method is called on each of them, it invokes the overridden method specific to their respective classes, demonstrating polymorphism.

Inheritance

Inheritance in Java is the ability that allows a new class (derived or subclass) to inherit properties and behaviours from an existing class (base or superclass). This concept helps us to eliminate code redundancy and promotes code reusability.

In Java, inheritance is implemented using the "extends" keyword. There are two main types of inheritance: single inheritance (where a subclass inherits from a single superclass) and multiple inheritance (where a subclass inherits from multiple superclasses, not directly supported in Java).

class Vehicle {
    void start() {
        System.out.println("Vehicle started.");
    }
}

class Car extends Vehicle {
    void drive() {
        System.out.println("Car is being driven.");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.start(); // Inherited from Vehicle
        myCar.drive(); // Specific to Car
    }
}

In this example, the Car class inherits the start method from the Vehicle class. When we create an instance of Car, we can use both the inherited method and the specific method of the Car class. This illustrates the concept of inheritance in Java, where a subclass inherits the attributes and behaviours of its superclass while also being able to provide its unique features.

Conclusion

In conclusion, these four pillars of Object-Oriented Programming are essential principles that guide the design and development of Java applications. They enable developers to create organized, secure, and maintainable code while promoting code reuse and flexibility. Understanding these concepts is fundamental for anyone looking to excel in Java programming and object-oriented software development.