Inheritance in Java
Table of Contents + −
Inheritance is one of the fundamental concepts of object-oriented programming (OOP) that allows a class to inherit properties and methods from another class. This promotes code reuse and establishes a relationship between classes.
Basic Inheritance
In Java, inheritance is implemented using the extends
keyword. The class that inherits is called the subclass or child class, and the class being inherited from is called the superclass or parent class.
// Superclass (Parent class)public class Animal { protected String name; protected int age;
public Animal(String name, int age) { this.name = name; this.age = age; }
public void makeSound() { System.out.println("Some sound"); }
public void displayInfo() { System.out.println("Name: " + name + ", Age: " + age); }}
// Subclass (Child class)public class Dog extends Animal { private String breed;
public Dog(String name, int age, String breed) { super(name, age); // Call the superclass constructor this.breed = breed; }
@Override public void makeSound() { System.out.println("Woof!"); }
public void fetch() { System.out.println(name + " is fetching the ball"); }
@Override public void displayInfo() { super.displayInfo(); // Call the superclass method System.out.println("Breed: " + breed); }}
Types of Inheritance
Java supports several types of inheritance:
1. Single Inheritance
A class extends only one class. Java supports only single inheritance for classes.
public class B extends A { // B inherits from A}
2. Multilevel Inheritance
A class extends a class that extends another class, forming a chain.
public class A { // Class A}
public class B extends A { // B inherits from A}
public class C extends B { // C inherits from B, which inherits from A}
3. Hierarchical Inheritance
Multiple classes extend the same class.
public class A { // Class A}
public class B extends A { // B inherits from A}
public class C extends A { // C also inherits from A}
4. Multiple Inheritance (Through Interfaces)
A class can implement multiple interfaces, achieving a form of multiple inheritance.
public interface Interface1 { void method1();}
public interface Interface2 { void method2();}
public class MyClass implements Interface1, Interface2 { @Override public void method1() { // Implementation }
@Override public void method2() { // Implementation }}
The super
Keyword
The super
keyword refers to the superclass objects and is used to:
- Call the superclass constructor
- Access superclass methods
- Access superclass fields
public class Subclass extends Superclass { public Subclass() { super(); // Call the superclass constructor }
public void method() { super.method(); // Call the superclass method System.out.println(super.field); // Access the superclass field }}
Method Overriding
Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass.
public class Animal { public void makeSound() { System.out.println("Some sound"); }}
public class Dog extends Animal { @Override public void makeSound() { System.out.println("Woof!"); }}
public class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow!"); }}
Rules for method overriding:
- The method signature (name and parameters) must be the same
- The return type must be the same or a subtype (covariant return type)
- The access modifier must be the same or less restrictive
- The method cannot throw more exceptions than the superclass method
Polymorphism
Polymorphism is the ability of an object to take many forms. In Java, polymorphism is mainly divided into two types:
1. Compile-time Polymorphism (Method Overloading)
Method overloading allows a class to have multiple methods with the same name but different parameters.
public class Calculator { public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
public int add(int a, int b, int c) { return a + b + c; }}
2. Runtime Polymorphism (Method Overriding)
Runtime polymorphism is achieved through method overriding, where the method to be called is determined at runtime.
Animal animal1 = new Dog("Buddy", 3, "Golden Retriever");Animal animal2 = new Cat("Whiskers", 2);
animal1.makeSound(); // Output: Woof!animal2.makeSound(); // Output: Meow!
The final
Keyword
The final
keyword can be used to:
- Prevent inheritance:
public final class MyClass { ... }
- Prevent method overriding:
public final void method() { ... }
- Create constants:
public static final double PI = 3.14159;
Best Practices
- Favor Composition Over Inheritance: Use composition when possible, as it provides more flexibility.
- Keep Inheritance Hierarchies Shallow: Deep inheritance hierarchies can be difficult to maintain.
- Use
@Override
Annotation: Always use the@Override
annotation when overriding methods to catch errors. - Design for Extension: Design classes with inheritance in mind, making methods protected when appropriate.
- Follow the Liskov Substitution Principle: Subtypes must be substitutable for their base types.
Conclusion
Inheritance is a powerful mechanism in Java that promotes code reuse and establishes relationships between classes. Understanding inheritance and polymorphism is essential for effective object-oriented programming in Java.