Every Java beginner hits the same wall: you cannot extend more than one class. This restriction is not laziness on the language designers' part. It is a deliberate trade-off to avoid the "diamond problem" that plagues multiple inheritance.
If you have ever stared at a compile error trying to extend two classes, this is why.
Key facts
- Java allows extending one class, but implementing multiple interfaces.
- The restriction exists to avoid the diamond problem.
- The diamond problem creates ambiguity when two parent classes share a method.
- Interfaces solve the use case through a different mechanism.
- Abstract methods in interfaces replace concrete methods in parent classes.
The mechanics of the ban
Multiple inheritance means a class can inherit behaviour from more than one parent. Java rejects this because the language designers wanted predictable method resolution. If class D extends both B and C, and both B and C override the same method from A, the runtime has no clean way to know which version D should use. That ambiguity is the diamond problem.
The error is not theoretical. Write a class that extends two parents in Java and the compiler refuses outright with a syntax error.
How Java routes around it
The workaround is the interface. Interfaces declare method signatures without providing implementation. A class can implement several interfaces and inherit method contracts from each. The actual method body is provided in the implementing class, so there is no ambiguity to resolve.
Worked example
Consider modelling a mobile phone manufacturing system. You have a base class with shared functionality like battery management and processor handling. You want a smartphone class that inherits the battery logic and a tablet class that inherits the processor logic. Single inheritance handles that fine.
Now imagine you want a foldable device class that needs both battery and processor logic. Single inheritance forces you to pick one parent or duplicate code. Interfaces solve this: define `BatteryInterface` and `ProcessorInterface`, and let the foldable class implement both. No ambiguity, no duplication.
Why the ban exists
The diamond problem explains the core issue. Imagine an abstract class A with a method `perform()`. Subclass B and subclass C both extend A and override `perform()`. If Java allowed class D to extend both B and C, calling `perform()` on a D object would be ambiguous—should it use B's version or C's version? The language cannot decide, so it prohibits the scenario entirely.
The same ambiguity would plague any shared fields or default implementations across parent classes. By forcing single inheritance for classes, Java guarantees that method resolution remains deterministic.
Our analysis
The usual complaint is that Java is too restrictive. The honest answer is that the restriction buys you something valuable: predictable codebases. Method resolution is always clear—follow the single inheritance chain upward until you find the implementation.
The trade-off is real. You sometimes need to combine behaviours from two existing class hierarchies. Java forces you to refactor toward interfaces early, which is more work up front and less pain later. That is a fair deal for most projects.
Where this hurts is in legacy codebases that pre-date the interface-first mindset. Refactoring a class hierarchy to use interfaces after the fact is painful and often impossible without breaking changes. If you inherit one of these codebases, the workaround is often composition, not inheritance.
What to watch
For new code, default to interfaces for shared contracts and use class inheritance only when you genuinely need an "is-a" relationship with implementation reuse. The pattern is "favour composition over inheritance" with a thin inheritance layer where it actually fits.
Bottom line: the ban on extending multiple classes is a feature, not a bug. Lean into interfaces and the design gets cleaner.
Key takeaways
- Java bans multiple class extension to avoid the diamond problem and keep method resolution predictable.
- Interfaces are the official workaround: a class can implement many, and each provides its own method bodies.
- Use interfaces for shared contracts and reserve class inheritance for genuine "is-a" relationships with implementation reuse.
- Composition is often the cleaner fix in legacy codebases where refactoring to interfaces is impractical.
Frequently asked questions
Can a Java class extend more than one class?
No. A Java class can extend exactly one parent class, though it can implement multiple interfaces.
What is the diamond problem in multiple inheritance?
It is the ambiguity that arises when a class inherits from two parents that both override the same method from a shared ancestor, leaving no clear way to choose which version to use.
Why do interfaces avoid the diamond problem?
Interfaces declare contracts without implementation (in older Java versions), and the implementing class provides the bodies, so there is no competing inherited behaviour to resolve.
When should I use composition instead of inheritance in Java?
When you need to combine behaviours from existing class hierarchies without a true "is-a" relationship, especially in legacy code where introducing interfaces would require breaking changes.