Inheritances is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit properties and behaviors (fields and methods) from another class. This promotes code reuse, modularity, and easier maintenance. In Java inheritances helps establish a hierarchical relationship between classes.
Inheritances allows one class (subclass or derived class) to inherit fields and methods from another class (superclass or base class). The subclass can also add new fields and methods or override existing ones.
Java supports several types of inheritances:
In single inheritances, one class inherits from one superclass.
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited method
dog.bark(); // Method from Dog class
}
}
//output
This animal eats food.
The dog barks.
In multilevel inheritances, a class inherits from another class, forming a chain.
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}
class Puppy extends Dog {
void weep() {
System.out.println("The puppy weeps.");
}
}
public class Main {
public static void main(String[] args) {
Puppy puppy = new Puppy();
puppy.eat(); // Inherited from Animal
puppy.bark(); // Inherited from Dog
puppy.weep(); // Method from Puppy class
}
}
//output
This animal eats food.
The dog barks.
The puppy weeps.
In hierarchical inheritances, multiple classes inherit from a single superclass.
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}
class Cat extends Animal {
void meow() {
System.out.println("The cat meows.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.eat(); // Inherited from Animal
dog.bark(); // Method from Dog
cat.eat(); // Inherited from Animal
cat.meow(); // Method from Cat
}
}
//output
This animal eats food.
The dog barks.
This animal eats food.
The cat meows.
Java does not allow multiple inheritance with classes to avoid ambiguity. However, it can be achieved through interfaces.
interface CanFly {
void fly();
}
interface CanSwim {
void swim();
}
class Duck implements CanFly, CanSwim {
public void fly() {
System.out.println("The duck flies.");
}
public void swim() {
System.out.println("The duck swims.");
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly(); // Method from CanFly
duck.swim(); // Method from CanSwim
}
}
//output
The duck flies.
The duck swims.
super
KeywordThe super
keyword is used to access members (fields and methods) of the superclass.
super
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
void eat() {
super.eat(); // Calling the superclass method
System.out.println("The dog eats dog food.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Calls Dog's eat method
}
}
//output
This animal eats food.
The dog eats dog food.
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The method in the subclass must have the same name, return type, and parameters.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // Upcasting
myDog.sound(); // Calls Dog's sound method
}
}
//output
Dog barks
An abstract class cannot be instantiated and can contain abstract methods (methods without implementation) that must be implemented by subclasses.
abstract class Animal {
abstract void sound(); // Abstract method
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // Upcasting
myDog.sound(); // Calls Dog's sound method
}
}
//output
Dog barks
Diamond Problem: This occurs when two classes inherit from the same superclass, and a subclass inherits from both. Java resolves this issue through interfaces, but it can still lead to ambiguity.
Inappropriate Use of protected
: Using protected
can expose fields and methods to unintended classes, potentially breaking encapsulation.
Overusing Inheritance: Avoid using inheritance for classes that do not share a common behavior or state. Consider using interfaces or composition instead.
Ignoring final
Keyword: If a class is declared as final
, it cannot be subclassed. Be cautious with the use of the final
keyword if you want to allow future extensions.