Skip to content
PickNTech

Inheritance, Interfaces and Polymorphism

Reuse and extend behaviour with inheritance, and program to interfaces for flexible code.

Beginner20 minUpdated 21 Sept 2026

What you’ll learn

  • extends, super and method overriding
  • Abstract classes vs interfaces
  • Polymorphism in practice
  • Why "composition over inheritance" matters

Inheritance

A class can extend another class and inherit its fields and methods:

public class Vehicle {
    protected final String plate;
 
    public Vehicle(String plate) { this.plate = plate; }
 
    public int wheels() { return 4; }
}
 
public class Motorbike extends Vehicle {
    public Motorbike(String plate) {
        super(plate); // call the parent constructor
    }
 
    @Override
    public int wheels() { return 2; }
}

@Override asks the compiler to verify you really are overriding a parent method — always use it.

Interfaces

An interface describes what something can do, without saying how:

public interface PaymentGateway {
    Receipt charge(String customerId, long amountPaise);
}
 
public class RazorpayGateway implements PaymentGateway {
    public Receipt charge(String customerId, long amountPaise) { /* ... */ }
}
 
public class StripeGateway implements PaymentGateway {
    public Receipt charge(String customerId, long amountPaise) { /* ... */ }
}

A class can implement many interfaces but extend only one class.

Polymorphism

Polymorphism means "one reference type, many runtime behaviours." Code written against the interface works with any implementation:

public class CheckoutService {
    private final PaymentGateway gateway;
 
    public CheckoutService(PaymentGateway gateway) {
        this.gateway = gateway;
    }
 
    public Receipt pay(Order order) {
        return gateway.charge(order.customerId(), order.totalPaise());
    }
}

CheckoutService has no idea which gateway it's using — and doesn't need to. Swap Razorpay for Stripe, or for a fake in tests, without touching this class. This exact pattern is how Spring's dependency injection works, so it's worth really understanding now.

CheckoutService→PaymentGateway (interface)→Razorpay | Stripe | FakeGateway
Depend on the interface, choose the implementation at runtime.

Abstract classes vs interfaces

Abstract classInterface
Can hold state (fields)YesNo (only constants)
ConstructorsYesNo
Multiple inheritanceNo — one parentYes — many interfaces
Use it forSharing code between closely related classesDefining a capability/contract

Composition over inheritance

Deep inheritance trees become brittle fast. Prefer giving a class the objects it needs (composition, as CheckoutService does above) over extending classes to reuse code.

⚡ Try it yourself

Define a Shape interface with an area() method. Implement Circle and Rectangle, put a few of each in a List<Shape>, and print the total area with a single loop.

Interview questions

QWhat is the difference between overloading and overriding?+

Overloading is multiple methods with the same name but different parameter lists in the same class, resolved at compile time. Overriding is a subclass providing its own implementation of a parent method with the same signature, resolved at runtime.

QCan an interface have method implementations?+

Yes. Since Java 8, interfaces can have default and static methods, and since Java 9 private methods. They still cannot hold instance state.

Key takeaways

  • extends for one parent class, implements for many interfaces.
  • Program to interfaces so implementations can be swapped.
  • Prefer composition to deep inheritance hierarchies.

Finished this lesson?

Mark it complete to move forward on your roadmap.