Inheritance and Its Types

Difficulty: Beginner

Question

What is inheritance? Explain the types of inheritance and which of them Java supports directly.

Answer

Inheritance is the mechanism by which one class, the child or subclass, acquires the fields and behaviour of another class, the parent or superclass. Let's understand why it exists and where it helps, and also where it bites.

The everyday analogy is a family. A child inherits traits from parents but is also free to develop new ones. In code, if you have Animal with eat and sleep, then Dog can extend Animal and immediately get both, adding bark on its own. This models an is-a relationship (a Dog is an Animal) and avoids copy-pasting common code. It is also the foundation of run-time polymorphism, since a parent reference can hold any child object.

The commonly listed types are these. Single inheritance: one class extends exactly one class. Multilevel: a chain such as Animal to Dog to Puppy, where Puppy gets everything from both ancestors. Hierarchical: several classes extend the same parent, like Dog and Cat both extending Animal. Multiple inheritance: a class has more than one direct parent. Hybrid: a combination of the above, typically involving multiple inheritance.

What does Java support? Single, multilevel, and hierarchical inheritance work with classes. Java deliberately disallows multiple inheritance of classes to avoid the diamond problem and the ambiguity of which parent's implementation to use. However, a class can implement multiple interfaces, which gives you multiple inheritance of type (and, since default methods arrived, a limited form of behaviour). C++ supports full multiple inheritance, and Python does too, resolving conflicts via the method resolution order.

Key rules to remember for Java. Use the extends keyword for classes and implements for interfaces. Every class implicitly extends Object if you do not specify a parent. Constructors are not inherited, but the child constructor always calls a parent constructor first, either explicitly with super(...) or implicitly with the no-argument one. Private members exist in the child object but are not directly accessible. Final classes cannot be extended and final methods cannot be overridden. Static methods are not overridden, they are hidden.

Now the mature perspective that interviewers at product companies like to hear. Inheritance is the tightest coupling you can create between two classes, because the child depends on the parent's implementation details, not just its public API. Change the parent and you may silently break every child. That is the fragile base class problem. So the modern guideline is to inherit only for true is-a relationships where the child can honour the parent's contract, and to prefer composition otherwise. Also keep hierarchies shallow; a chain more than two or three levels deep is usually a smell.

The example below shows a multilevel chain and a class picking up two capabilities through interfaces.

Code examples

Multilevel inheritance

class Animal {
    void eat() { System.out.println("eats"); }
}
class Dog extends Animal {
    void bark() { System.out.println("barks"); }
}
class Puppy extends Dog {
    void weep() { System.out.println("weeps"); }
}

public class InheritanceDemo {
    public static void main(String[] args) {
        Puppy p = new Puppy();
        p.eat();    // from Animal
        p.bark();   // from Dog
        p.weep();   // own method
    }
}

Multiple inheritance of type through interfaces

interface Flyer   { default void move() { System.out.println("flies"); } }
interface Swimmer { void swim(); }

class Duck implements Flyer, Swimmer {
    public void swim() { System.out.println("swims"); }
}

public class DuckDemo {
    public static void main(String[] args) {
        Duck d = new Duck();
        d.move();
        d.swim();
    }
}

Key points

Concepts covered

inheritance, extends, multilevel, is-a