Introduction
Inheritance is one of the four pillars of Object-Oriented Programming (OOP)—alongside encapsulation, abstraction, and polymorphism. In Java, inheritance allows one class to inherit the fields and methods of another, promoting code reuse, scalability, and logical hierarchy.
This tutorial explains the concept of inheritance in Java in simple terms, while also diving into advanced topics like method overriding, constructor chaining, super
, and sealed classes. Whether you're a beginner or a senior developer, mastering inheritance will help you design more modular, maintainable software.
What Is Inheritance in Java?
Theoretical Foundation
Inheritance is a mechanism in which a new class (subclass or derived class) inherits the properties and behavior of an existing class (superclass or base class).
- Promotes code reuse
- Establishes "is-a" relationships
- Enables polymorphism
Real-World Analogy
Think of a car and an electric car. An electric car is a car but with added behavior (battery charging). It inherits basic characteristics like wheels, doors, and the ability to drive.
Java Syntax for Inheritance
Basic Syntax
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}
Usage
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited from Animal
dog.bark(); // Defined in Dog
}
}
UML-Style Representation
Superclass: Animal
|-- +eat(): void
Subclass: Dog extends Animal
|-- +bark(): void
Java Behavior and Edge Cases
- Java supports single inheritance (only one parent class).
- Use
super
to call superclass methods or constructors. - Constructors are not inherited, but can be accessed via
super()
. - Private members of the superclass are not inherited directly.
- Method overriding allows subclasses to provide specific behavior.
Example: Method Overriding
class Animal {
void sound() {
System.out.println("Animal makes sound");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Meow");
}
}
Real-World Use Cases
- Creating a hierarchy in domain models (e.g., Employee > Manager)
- Extending abstract framework classes (e.g., Servlet, Spring Controllers)
- Implementing polymorphism in design patterns like Template or Strategy
- Code sharing in similar classes (e.g., Shapes like Circle, Rectangle)
Pros and Cons of Inheritance
✅ Pros
- Promotes code reuse and hierarchy
- Simplifies code by abstracting shared logic
- Enables polymorphism and runtime method binding
❌ Cons
- Tight coupling between classes
- Can lead to fragile base class problem
- Not ideal for all use cases (prefer composition in many cases)
Common Misuse Cases
Misuse | Correction |
---|---|
Overusing inheritance for code reuse | Prefer composition where possible |
Deep inheritance chains | Flatten hierarchy |
Inheriting unrelated behavior | Use interfaces or separate classes |
Ignoring @Override annotation |
Always use it to catch errors |
Comparison with Related Concepts
Concept | Description |
---|---|
Inheritance vs Composition | Inheritance creates "is-a", composition creates "has-a" relationships |
Inheritance vs Interface | Interface offers contract without implementation |
Inheritance vs Abstraction | Abstraction hides implementation; inheritance shares it |
Refactoring Example
Before (Code Duplication):
class Dog {
void eat() {
System.out.println("Eating");
}
void bark() {
System.out.println("Barking");
}
}
class Cat {
void eat() {
System.out.println("Eating");
}
void meow() {
System.out.println("Meowing");
}
}
After (Using Inheritance):
class Animal {
void eat() {
System.out.println("Eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Barking");
}
}
class Cat extends Animal {
void meow() {
System.out.println("Meowing");
}
}
Best Practices
- Keep base classes abstract or general-purpose.
- Favor composition for unrelated behavior sharing.
- Use
@Override
to make overrides explicit. - Don’t expose fields—use protected methods instead.
- Avoid inheritance just for method reuse.
Java 17/21 Feature Notes
sealed
Classes (Java 17+)
Control which classes can inherit from a base class.
sealed class Vehicle permits Car, Bike {}
final class Car extends Vehicle {}
final class Bike extends Vehicle {}
Conclusion
Inheritance is a foundational concept in Java OOP that allows you to model hierarchical relationships between classes. When used thoughtfully, it promotes code reuse and simplifies your application architecture. However, like any powerful tool, it must be used judiciously—favoring composition when appropriate and avoiding deep inheritance trees.
Key Takeaways
- Inheritance models an "is-a" relationship.
- Java supports single inheritance via
extends
keyword. - Enables code reuse and polymorphic behavior.
- Use sealed classes (Java 17+) for more control.
- Prefer composition for flexible designs.
FAQ – Inheritance in Java
1. Can a class inherit multiple classes in Java?
No, Java supports single inheritance only.
2. Can interfaces be used to simulate multiple inheritance?
Yes. A class can implement multiple interfaces.
3. Are constructors inherited in Java?
No. They must be explicitly defined in subclasses, but super()
can be used.
4. What is the role of super
keyword?
Used to call superclass constructors or methods.
5. Can private methods be inherited?
No. Private members are not inherited.
6. What is method overriding?
Subclasses redefine a method of the parent class for specialized behavior.
7. Is inheritance always the right choice?
No. Use only when a clear "is-a" relationship exists.
8. What is constructor chaining?
Calling one constructor from another using this()
or super()
.
9. Can abstract classes be inherited?
Yes. But they must be extended and implemented by the subclass.
10. What are sealed classes?
A Java 17+ feature to restrict which classes can extend a superclass.