› Module 6: The Four Pillars of OOP › 6.3 Polymorphism: Overloading vs Overriding
M O D U L E

Module 6: The Four Pillars of OOP

Encapsulation with access control, inheritance hierarchies, runtime polymorphism, and abstraction with abstract classes & interfaces.

6.1 Encapsulation

Encapsulation is the principle of bundling data fields and the methods that operate on that data into a single unit (the class), while deliberately restricting direct outside access to internal state.

In practice, encapsulation is implemented by declaring fields private and providing controlled public gateway methods (getters and setters). This allows validation, state integrity, and internal representation changes without breaking client code:

class Account {
    private double balance; // hidden internal state

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount; // business rule validation
        }
    }
}
private double balance; public double getBalance() public void deposit(double a) Outside code
Figure 6.1 — Encapsulation: internal state is hidden, and access is only possible through the class's public methods.

💡 Placement & Interview Deep-Dive

  • How to create a Fully Immutable Class in Java?
    1. Declare the class as final so it cannot be subclassed.
    2. Declare all fields as private and final.
    3. Do NOT provide any setter methods.
    4. Initialize all fields through a parameterized constructor.
    5. Perform Defensive Copying when returning or receiving mutable objects (like Date or List).

6.2 Inheritance

Inheritance allows a new class (subclass/child) to acquire the non-private properties and methods of an existing class (superclass/parent) using the extends keyword. It represents an "is-a" relationship:

class Animal {
    void eat() { System.out.println("eating"); }
}

class Dog extends Animal {
    void bark() { System.out.println("woof"); }
}

Dog d = new Dog();
d.eat();  // inherited from Animal
d.bark(); // defined in Dog
class Animal (superclass) class Dog extends Animal (subclass) class Cat extends Animal (subclass)
Figure 6.2 — A subclass inherits from, and can specialize, its superclass.

💡 Placement & Interview Deep-Dive

  • Single Inheritance Constraint: Java supports single inheritance only for classes — a class can extend exactly one direct superclass. This avoids the infamous "Diamond Problem" of multiple inheritance found in C++. Multiple inheritance of type is supported through interfaces.
  • What is the universal root superclass? java.lang.Object is the ultimate ancestor of every class in Java. If a class does not explicitly specify an extends clause, the compiler silently inserts extends Object.
  • What does the super keyword do?
    • super() invokes the parent class constructor (must be the first line in the child constructor).
    • super.method() calls an overridden superclass method from within the subclass.

6.3 Polymorphism: Overloading vs Overriding

Polymorphism ("many forms") is the capability of a method to exhibit different behaviors based on context. Java implements polymorphism in two forms:

  • Compile-Time Polymorphism (Method Overloading): Multiple methods in the same class sharing the same name but different parameters. Resolved by the compiler at compile-time.
  • Runtime Polymorphism (Method Overriding): A subclass redefines a method inherited from its superclass with the exact same name, return type, and parameters. The JVM resolves which method to invoke dynamically at runtime based on the actual object on the heap, regardless of the reference type:
    Animal a = new Dog(); // Superclass reference, Subclass object
    a.sound(); // Calls Dog's overridden sound() method at runtime!
Compile-time (Overloading) add(int, int) add(double, double) -- same name, different parameter list -- resolved at compile time Runtime (Overriding) Animal a = new Dog(); a.sound(); -- resolved at runtime, -- by actual object type
Figure 6.3 — Overloading is resolved at compile time; overriding is resolved at runtime.

💡 Placement & Interview Deep-Dive: The 5 Overriding Rules

  1. Signature Rule: Method name and parameter types must be identical.
  2. Covariant Return Type: The overriding method can return a subtype of the superclass method's return type.
  3. Access Modifier Rule: The overriding method cannot have a more restrictive access modifier (e.g. A protected method cannot be overridden as private; it can be protected or public).
  4. Exception Handling Rule: The overriding method cannot throw broader or new checked exceptions than declared in the parent method. It can throw narrower subclasses, fewer checked exceptions, or any unchecked exceptions.
  5. What CANNOT be overridden? private methods (not visible), static methods (method hiding, not overriding), and final methods (cannot be changed).

6.4 Abstraction: Abstract Classes and Interfaces

Abstraction is the process of hiding implementation complexity and showing only essential feature interfaces to the user. Java provides two mechanisms for abstraction:

  • Abstract Class (abstract): A class that cannot be instantiated directly with new. It can contain both concrete methods (with bodies) and abstract methods (without bodies):
    abstract class Shape {
        abstract double area(); // abstract method: subclasses must implement
        void display() { System.out.println("Shape rendered"); } // concrete method
    }
  • Interface (interface): A contract specifying what a class must do, but not how. A class uses the implements keyword to implement an interface. A single class can implement multiple interfaces:
    interface Drawable {
        void draw(); // implicitly public abstract
    }
KEY TERM: Abstract Class vs. Interface

Reach for an abstract class when subclasses share common, reusable code as well as a contract. Reach for an interface when you need to define a contract across classes that may be otherwise unrelated, or when you need multiple inheritance of type.

💡 Placement & Interview Deep-Dive

  • Modern Interface Features (Java 8 & 9+):
    • Default Methods (Java 8+): Interfaces can provide concrete method implementations using the default keyword without breaking existing implementing classes.
    • Static Methods (Java 8+): Utility methods belonging to the interface itself.
    • Private Methods (Java 9+): Internal helper methods shared between default methods.
  • Can an abstract class have a constructor? YES! Although an abstract class cannot be instantiated directly via new AbstractClass(), its constructor runs when a concrete subclass is instantiated via super().
MODULE COMPREHENSIVE QUIZ

Module 6 Final Quiz

Test your understanding across all 4 topics of this module with interview-grade questions, tricky edge cases, and code output predictions.

Take Module 6 Final Quiz →
Yukti Mascot