Sitemap
Mahi Mullapudi

Mahi Mullapudi

Engineering @Microsoft. Expert in tech with over a decade of experience in system design, architectural patterns, cloud infrastructure and security.

Inheritance in Java

5 min readJun 12, 2024

--

Inheritance in Java

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a new class to inherit properties and behaviors (fields and methods) from an existing class. This mechanism promotes code reuse, modularity, and extensibility. In Java, inheritance is achieved using the extends keyword.

Key Concepts of Inheritance

  • Super Class (Parent Class): The class whose properties and methods are inherited by another class.
  • Sub Class (Child Class): The class that inherits the properties and methods from another class.
  • Reusability: Inheritance allows the reuse of code, which can reduce redundancy and enhance maintainability.
  • Method Overriding: Subclasses can provide a specific implementation of a method already defined in its superclass.

Basic Syntax

What is a Class?

In Java, a class is like a blueprint for creating objects (think of objects as things or entities). A class defines the properties (fields) and behaviors (methods) that the objects created from the class can have.

SuperClass

Let’s look at the SuperClass first:

class SuperClass {
// fields and methods
}
  • class SuperClass: This line defines a new class named SuperClass.
  • fields and methods: These are placeholders where you would define the properties and behaviors for objects of this class. For example, fields could be variables like int age or String name, and methods could be actions like void speak().

SubClass

Now let’s look at the SubClass:

class SubClass extends SuperClass {
// additional fields and methods
}
  • class SubClass: This line defines a new class named SubClass.
  • extends SuperClass: This part means that SubClass is inheriting from SuperClass. Inheritance is like saying "SubClass is a specialized version of SuperClass." It means that SubClass will have all the fields and methods of SuperClass, plus it can have its own additional fields and methods.

Example of Inheritance

Imagine SuperClass is like a general blueprint for a "Vehicle" and SubClass is a specific type of vehicle, like a "Car". Here's a simple example to illustrate:

Press enter or click to view image in full size
Inheritance using Vehicle relations
class Vehicle {
int speed;

void move() {
System.out.println("Vehicle is moving at speed: " + speed);
}
}

class Car extends Vehicle {
int numberOfDoors;

void honk() {
System.out.println("Car is honking!");
}
}
  • Vehicle: This is the SuperClass. It has a field speed and a method move().
  • Car: This is the SubClass that extends Vehicle. It inherits the field speed and the method move() from Vehicle, and it adds its own field numberOfDoors and method honk().

When you create an object of Car, it can do everything a Vehicle can do, plus the extra things that only a Car can do.

Using the Classes

Here’s how you might create and use objects of these classes:

public class Main {
public static void main(String[] args) {
Vehicle myVehicle = new Vehicle();
myVehicle.speed = 50;
myVehicle.move(); // Output: Vehicle is moving at speed: 50

Car myCar = new Car();
myCar.speed = 70;
myCar.numberOfDoors = 4;
myCar.move(); // Output: Vehicle is moving at speed: 70
myCar.honk(); // Output: Car is honking!
}
}
  • We create a Vehicle object myVehicle and set its speed to 50, then call its move() method.
  • We create a Car object myCar, set its speed to 70 and numberOfDoors to 4. When we call myCar.move(), it uses the move() method from Vehicle. When we call myCar.honk(), it uses the honk() method defined in Car.

Let’s look at another example where

// Superclass
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Subclass
class Dog extends Animal {
void bark() {
System.out.println("The dog barks.");
}
}

// Subclass
class Lion extends Animal {
void roar() {
System.out.println("The lion roars.");
}
}

// Test Class
public class TestInheritance {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited method from Animal
dog.bark(); // Method from Dog class

Lion lion = new Lion();
lion.eat();
lion.roar();
}
}

Types of Inheritance in Java

Java supports single inheritance, multiple inheritance through interfaces, and hierarchical inheritance. It does not support multiple inheritance through classes directly to avoid complexity and ambiguity.

1. Single Inheritance

In single inheritance, a class inherits from only one superclass.

  class SuperClass {
// fields and methods
}

class SubClass extends SuperClass {
// additional fields and methods
}

2. Multilevel Inheritance

In multilevel inheritance, a class is derived from another class, which is also derived from another class.

  class A {
// fields and methods
}

class B extends A {
// additional fields and methods
}

class C extends B {
// additional fields and methods
}

3. Hierarchical Inheritance

In hierarchical inheritance, multiple classes inherit from a single superclass.

  class SuperClass {
// fields and methods
}

class SubClass1 extends SuperClass {
// additional fields and methods
}

class SubClass2 extends SuperClass {
// additional fields and methods
}

Method Overriding

Method overriding allows a subclass to provide a specific implementation of a method already defined in its superclass. This is a key feature of polymorphism in Java.

  class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}

public class TestOverride {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.sound(); // Calls the overridden method in Dog class
}
}

super Keyword

The super keyword is used to refer to the immediate parent class object. It can be used to access methods and fields of the parent class, and to call the parent class constructor.

Accessing Parent Class Methods and Fields

  class Animal {
String name = "Animal";

void display() {
System.out.println("This is an animal.");
}
}

class Dog extends Animal {
String name = "Dog";

void display() {
System.out.println("This is a dog.");
}

void show() {
super.display(); // Calls the display method of Animal class
System.out.println("Animal name: " + super.name); // Accesses the name field of Animal class
}
}

public class TestSuper {
public static void main(String[] args) {
Dog dog = new Dog();
dog.show();
}
}

Calling Parent Class Constructor

  class Animal {
Animal() {
System.out.println("Animal constructor called");
}
}

class Dog extends Animal {
Dog() {
super(); // Calls the constructor of Animal class
System.out.println("Dog constructor called");
}
}

public class TestSuperConstructor {
public static void main(String[] args) {
Dog dog = new Dog();
}
}

Benefits of Inheritance

  • Code Reusability: Inheritance allows for the reuse of existing code, reducing redundancy and maintenance efforts.
  • Method Overriding: Subclasses can override methods to provide specific implementations, enhancing flexibility.
  • Polymorphism: Inheritance supports polymorphism, allowing objects to be treated as instances of their parent class, promoting code generalization.

Limitations of Inheritance

  • Tight Coupling: Inheritance creates a tightly coupled relationship between the superclass and subclasses, making changes to the superclass potentially impact all subclasses.
  • Fragile Base Class Problem: Changes in the superclass can inadvertently affect the behavior of subclasses.
  • Multiple Inheritance Issue: Java does not support multiple inheritance with classes to avoid complexity and ambiguity, though it allows multiple inheritance through interfaces.

Best Practices

  • Use inheritance only when there is a clear “is-a” relationship between the superclass and subclass.
  • Favor composition over inheritance to achieve greater flexibility and to avoid tight coupling.
  • Avoid deep inheritance hierarchies as they can become difficult to manage and understand.

By understanding inheritance, you can create more organized and modular code, promoting reuse and reducing redundancy. Proper use of inheritance can greatly enhance the design and maintainability of your software.

Get Mahi Mullapudi’s stories in your inbox

Join Medium for free to get updates from this writer.

Originally published at https://tutorialq.com.

--

--