Java Types of Inheritance

In the last lesson you learned about Java inheritance. You saw one child extend one parent with extends, but real programs rarely stop there. Let’s sort out every type of inheritance in Java, with runnable code for each one.

🤔 Why talk about “types” at all?

Classes connect into different shapes. Knowing the shape tells you instantly whether your code will compile.

  • Single inheritance: one parent, one child. A to B.
  • Multilevel inheritance: a chain. A to B to C.
  • Hierarchical inheritance: one parent, many children. A to B and A to C.
  • Multiple inheritance of classes: one child, many parent classes. Java does not allow this.
  • Multiple inheritance of type: one class implements many interfaces. Java does allow this.

1️⃣ Single inheritance (A → B)

The simplest shape. One parent, one child.

  • The child extends the parent with extends.
  • It gains the parent’s fields and methods for free.
  • It can add its own methods on top.
class Animal {
void eat() {
System.out.println("This animal eats food");
}
}
class Dog extends Animal { // ✅ single: Dog extends one parent
void bark() {
System.out.println("The dog barks");
}
}

So Dog has both eat and bark, even though it only wrote bark. Run it.

public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.eat(); // ✅ inherited from Animal
d.bark(); // ✅ its own method
}
}

Output

This animal eats food
The dog barks

2️⃣ Multilevel inheritance (A → B → C)

Now stretch it into a chain: Animal → Dog → Puppy. This is multilevel inheritance.

  • A child can itself become a parent.
  • There is more than one level above the bottom class.
  • The bottom class collects methods all the way up the chain.
class Animal {
void eat() {
System.out.println("Eating");
}
}
class Dog extends Animal { // level 1: Dog extends Animal
void bark() {
System.out.println("Barking");
}
}
class Puppy extends Dog { // level 2: Puppy extends Dog
void weep() {
System.out.println("Weeping");
}
}

Here a Puppy reaches every method above it.

public class Main {
public static void main(String[] args) {
Puppy p = new Puppy();
p.eat(); // ✅ from Animal (top of the chain)
p.bark(); // ✅ from Dog (middle of the chain)
p.weep(); // ✅ its own method
}
}

Output

Eating
Barking
Weeping

So Puppy reached all the way up to Animal for eat. Here is the shape.

Animal

Dog

Puppy

  • Arrows point from parent down to child.
  • Puppy sits at the bottom, so it owns the most.
  • The top class owns the least but is shared by everyone below.

The chain still builds parent-first

When you create a Puppy, Java builds the Animal part first, then the Dog part, then the Puppy part. The whole chain is set up from the top down. So super(...) in Puppy reaches Dog, and super(...) in Dog reaches Animal. Each link calls the one above it.

3️⃣ Hierarchical inheritance (A → B, A → C)

Sometimes many classes share one parent. Dog and Cat are both Animal. This is hierarchical inheritance.

  • One parent sits at the top of several children, like a small tree.
  • Each child extends the same parent.
  • Each child adds its own behavior.
class Animal {
void eat() {
System.out.println("Eating");
}
}
class Dog extends Animal { // ✅ child one
void bark() {
System.out.println("Barking");
}
}
class Cat extends Animal { // ✅ child two, same parent
void meow() {
System.out.println("Meowing");
}
}

Both children get eat from the shared parent, then add their own sound. Run both.

public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.eat(); // ✅ from Animal
d.bark(); // ✅ from Dog
Cat c = new Cat();
c.eat(); // ✅ same parent method, reused
c.meow(); // ✅ from Cat
}
}

Output

Eating
Barking
Eating
Meowing

eat ran for both, with no repeated code. The shared logic lives once in Animal. Here is the shape.

Animal

Dog

Cat

Add more animals later and they all reuse Animal for free.

🚫 Multiple inheritance of classes (not allowed)

Now the shape Java refuses. Multiple inheritance means one child extending more than one parent class at once.

  • You might want a Smartphone that is both a Phone and a Camera.
  • Java allows exactly one parent class.
  • So the code below is a hard compile error.
class Phone {
void call() { System.out.println("Calling"); }
}
class Camera {
void shoot() { System.out.println("Taking a photo"); }
}
class Smartphone extends Phone, Camera { } // ❌ will not compile

Java bans this because of the diamond problem.

Why: the diamond problem

Say both parents have a start() method.

  • Now Smartphone inherits two different start() methods.
  • Call phone.start() and Java has no rule to pick one.
  • The shape looks like a diamond, hence the name.

Device with start

Phone with start

Camera with start

Smartphone

Two arrows arrive at Smartphone and both paths lead back to the same top. The child is stuck with two competing versions. That ambiguity is the diamond problem, so Java bans it. One parent class, always.

✅ Multiple inheritance of type (interfaces)

But the need is real. A smartphone really does need to call and take photos. Java solves this with interfaces.

  • A class extends only one parent class.
  • But it can implement as many interfaces as you like.
  • An interface is a contract: a list of method names the class promises to provide.
  • The class writes the bodies itself, so no two bodies clash. The diamond problem disappears.
interface Phone {
void call();
}
interface Camera {
void shoot();
}
class Smartphone implements Phone, Camera { // ✅ many interfaces allowed
public void call() {
System.out.println("Calling a friend");
}
public void shoot() {
System.out.println("Taking a photo");
}
}

So Smartphone promised two contracts and wrote both bodies itself. Run it.

public class Main {
public static void main(String[] args) {
Smartphone s = new Smartphone();
s.call(); // ✅ from the Phone contract
s.shoot(); // ✅ from the Camera contract
}
}

Output

Calling a friend
Taking a photo

That gives you “many parents” without the ambiguity.

  • You can mix both: class Smartphone extends Device implements Phone, Camera.
  • One real “is-a” parent carries shared code.
  • The interfaces add extra abilities.
  • Interfaces get their own lesson later.

The easy way to remember it

Multiple inheritance of classes: not allowed. Multiple inheritance of type through interfaces: allowed. Classes carry real method bodies, so two of them clash. Interfaces are just promises, so the class writes one clear body and nothing clashes.

🆙 How extends builds the chain and super reaches the parent

Two keywords do the connecting work across every shape.

  • extends links a child to its parent.
  • super(...) calls the parent constructor.
  • super.method() calls the parent’s version of a method.
  • In a chain, each level uses super to reach the level right above it.
class Animal {
Animal() {
System.out.println("Animal part built");
}
void show() {
System.out.println("I am an animal");
}
}
class Dog extends Animal {
Dog() {
super(); // ✅ reaches Animal
System.out.println("Dog part built");
}
void show() {
super.show(); // ✅ run the parent's version first
System.out.println("I am a dog");
}
}
class Puppy extends Dog {
Puppy() {
super(); // ✅ reaches Dog, which reaches Animal
System.out.println("Puppy part built");
}
}

Now build a Puppy and call show.

public class Main {
public static void main(String[] args) {
Puppy p = new Puppy();
p.show();
}
}

Output

Animal part built
Dog part built
Puppy part built
I am an animal
I am a dog

Read the order.

  • The three “part built” lines came top to bottom, so the chain built from Animal down to Puppy.
  • show ran super.show() first, so Animal’s line printed before Dog’s.
  • Puppy did not write its own show, so it used the one inherited from Dog.

⚠️ Common Mistakes

A few inheritance shapes trip people up.

  • Trying to extend two classes. Java allows only one parent class. Extend one class and implement interfaces for the rest.
class Smartphone extends Phone, Camera { } // ❌ will not compile
class Smartphone extends Phone implements Camera { } // ✅ one class, one interface
  • Confusing “is-a” with “has-a”. Inheritance is for “is-a”. If the honest sentence is “X has a Y”, store a field instead. A Car has an Engine, it is not an engine.
class Car extends Engine { } // ❌ a car is not an engine
class Car { // ✅ a car HAS an engine
Engine engine;
}
  • Building deep hierarchies just because you can. A chain like A → B → C → D → E becomes painful. A change near the top breaks everything below. Keep chains shallow.
class E extends D { } // ❌ five levels deep, fragile and hard to follow
class Report { Formatter formatter; } // ✅ flatter design with a field

✅ Best Practices

Habits that keep your inheritance shapes clean.

  • Use single and hierarchical inheritance freely for true “is-a” cases. Dog is-a Animal, Cat is-a Animal, both fine.
  • Keep multilevel chains short. Two or three levels is usually plenty. Deep chains are hard to read and easy to break.
  • Use interfaces when you need behavior from several sources. That is Java’s clean answer to “multiple parents”.
  • Prefer composition over deep inheritance. A field is often more flexible than stacking parents, and you can swap it later.
  • Run the “is-a” test out loud before adding a parent. If “X is a Y” sounds wrong, use a field, not extends.

🧩 What You’ve Learned

Nicely done. Let’s recap the types of inheritance.

  • Single inheritance is one parent and one child, A to B.
  • Multilevel inheritance is a chain, A to B to C, where each class gets everything above it.
  • Hierarchical inheritance is one parent with many children, A to B and A to C, sharing one parent’s code.
  • ✅ Java does not allow multiple inheritance of classes because of the diamond problem: two parents with the same method create ambiguity.
  • ✅ Java does allow multiple inheritance of type through interfaces, since a class can implement many interfaces and write its own clear method bodies.
  • extends builds the chain, and super reaches the parent: super(...) for the constructor, super.method() for the method.
  • ✅ Keep chains shallow, use inheritance only for “is-a”, and prefer composition when in doubt.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Which shape is multilevel inheritance?

    Why: Multilevel inheritance is a chain where each class extends the one above it, like Animal to Dog to Puppy.

  2. 2

    Why does Java forbid multiple inheritance of classes?

    Why: If two parent classes define the same method, the child would have two versions and no rule to pick one. That ambiguity is the diamond problem.

  3. 3

    How does a Java class get behavior from more than one source?

    Why: A class extends one parent class but can implement many interfaces, giving multiple inheritance of type with no diamond problem.

  4. 4

    In a chain like Animal to Dog to Puppy, which constructor part is built first?

    Why: Java builds the chain from the top down, so the Animal part is set up first, then Dog, then Puppy.

🚀 What’s Next?

You now know how classes connect into single, multilevel, and hierarchical shapes, and why interfaces replace multiple inheritance. The next step is what happens when a child changes a method it inherited. That is method overriding, and it is where inheritance starts to feel powerful.

Java Method Overriding

Share & Connect