Object-Oriented Programming (OOPs) in Java

A deep dive into the fundamental concepts that make Java a powerful object-oriented language.

Encapsulation

Encapsulation is the bundling of data (attributes) and methods (functions) that operate on the data into a single unit or class. It restricts direct access to some of an object's components, which is a means of preventing unintended interference and misuse of the methods and data. The variables of a class will be hidden from other classes, and can be accessed only through the methods of their current class.

public class Person {
    private String name; // private = restricted access

    // Getter
    public String getName() {
        return name;
    }

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

Inheritance

Inheritance is a mechanism wherein a new class derives from an existing class. You can use inheritance to create a new class that has all the properties and behavior of an existing class, and you can add new properties and behavior to the new class. The class that is inherited from is called the superclass (or parent), and the class that does the inheriting is called the subclass (or child).

class Vehicle { // Superclass
    protected String brand = "Ford";
    public void honk() {
        System.out.println("Tuut, tuut!");
    }
}

class Car extends Vehicle { // Subclass
    private String modelName = "Mustang";
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.honk();
        System.out.println(myCar.brand + " " + myCar.modelName);
    }
}

Polymorphism

Polymorphism means "many forms", and it occurs when we have many classes that are related to each other by inheritance. Polymorphism allows us to perform a single action in different ways. For example, think of a superclass called `Animal` that has a method called `animalSound()`. Subclasses of Animals could be Pigs, Cats, Dogs, Birds - and they also have their own implementation of an animal sound.

class Animal {
    public void animalSound() {
        System.out.println("The animal makes a sound");
    }
}

class Pig extends Animal {
    public void animalSound() {
        System.out.println("The pig says: wee wee");
    }
}

class Dog extends Animal {
    public void animalSound() {
        System.out.println("The dog says: bow wow");
    }
}

Abstraction

Abstraction is the process of hiding the implementation details from the user, only the functionality will be provided to the user. In other words, the user will have the information on what the object does instead of how it does it. In Java, abstraction is achieved using abstract classes and interfaces. An abstract class can have abstract and non-abstract methods.

abstract class Animal { // Abstract class
    // Abstract method (does not have a body)
    public abstract void animalSound();
    
    // Regular method
    public void sleep() {
        System.out.println("Zzz");
    }
}

// Subclass (inherit from Animal)
class Pig extends Animal {
    public void animalSound() {
        // The body of animalSound() is provided here
        System.out.println("The pig says: wee wee");
    }
}