Inheritance

Inheritance is an important pillar of OOP (Object-Oriented Programming) which one class is allowed to inherit the features (fields and methods) of another class. Inheritance means creating new classes based on existing ones. A class that inherits from another class can reuse the methods and fields of that class. In addition, you can add new fields and methods to your current class as well

Important Terminologies Used in Inheritance

  • Class: Class is a set of objects which shares common characteristics/ behavior and common properties/ attributes. Class is not a real-world entity. It is just a template or blueprint or prototype from which objects are created.

  • Super Class/Parent Class: The class whose features are inherited is known as a superclass (or a base class or a parent class).

  • Sub Class/Child Class: The class that inherits the other class is known as a subclass (or a derived class, extended class, or child class). The subclass can add its own fields and methods in addition to the superclass fields and methods.

  • Reusability: Inheritance supports the concept of “reusability”, i.e. when we want to create a new class and there is already a class that includes some of the code that we want, we can derive our new class from the existing class. By doing this, we are reusing the fields and methods of the existing class.

How to Use Inheritance ?

The extends keyword is used for inheritance in Java. Using the extends keyword indicates you are derived from an existing class. In other words, “extends” refers to increased functionality.

Syntax :

Java
class derived-class extends base-class  
{  
   //methods and fields  
} 
C#
class derived-class : base-class
{
    //methods and fields
}

Example:

// Java program to illustrate the
// concept of inheritance

// base class
class Bicycle {
	// the Bicycle class has two fields
	public int gear;
	public int speed;

	// the Bicycle class has one constructor
	public Bicycle(int gear, int speed)
	{
		this.gear = gear;
		this.speed = speed;
	}

	// the Bicycle class has three methods
	public void applyBrake(int decrement)
	{
		speed -= decrement;
	}

	public void speedUp(int increment)
	{
		speed += increment;
	}

	// toString() method to print info of Bicycle
	public String toString()
	{
		return ("No of gears are " + gear + "\n"
				+ "speed of bicycle is " + speed);
	}
}

// derived class
class MountainBike extends Bicycle {

	// the MountainBike subclass adds one more field
	public int seatHeight;

	// the MountainBike subclass has one constructor
	public MountainBike(int gear, int speed, int startHeight)
	{
		// invoking base-class(Bicycle) constructor
		super(gear, speed);
		seatHeight = startHeight;
	}

	// the MountainBike subclass adds one more method
	public void setHeight(int newValue)
	{
		seatHeight = newValue;
	}

	// overriding toString() method
	// of Bicycle to print more info
	@Override public String toString()
	{
		return (super.toString() + "\nseat height is "
				+ seatHeight);
	}
}

// driver class
public class Test {
	public static void main(String args[])
	{

		MountainBike mb = new MountainBike(3, 100, 25);
		System.out.println(mb.toString());
	}
}

In the above program, when an object of MountainBike class is created, a copy of all methods and fields of the superclass acquires memory in this object. That is why by using the object of the subclass we can also access the members of a superclass.

Please note that during inheritance only the object of the subclass is created, not the superclass

In practice, inheritance, and polymorphism are used together to achieve fast performance and readability of code.

Inheritance Types

Below are the different types of inheritance

  1. Single Inheritance

  2. Multilevel Inheritance

  3. Hierarchical Inheritance

  4. Multiple Inheritance

  5. Hybrid Inheritance

1. Single Inheritance

In single inheritance, a single derived class inherits from a single base class.

// Java program to illustrate the
// concept of single inheritance
import java.io.*;
import java.lang.*;
import java.util.*;
  
// Parent class
class one {
    public void print_1()
    {
        System.out.println("Me");
    }
}
  
class two extends one {
    public void print_2() 
    { 
        System.out.println("and");
    }
}
  
// Driver class
public class Main {
      // Main function
    public static void main(String[] args)
    {
        two g = new two();
        g.print_1();
        g.print_2();
        g.print_1();
    }
}

Output

Me
and
Me

2. Multilevel Inheritance

In Multilevel Inheritance, a derived class will be inheriting a base class, and as well as the derived class also acts as the base class for other classes. In the below image, class A serves as a base class for the derived class B, which in turn serves as a base class for the derived class C. A class cannot directly access the grandparent’s members.

// Java program to illustrate the
// concept of Multilevel inheritance
import java.io.*;
import java.lang.*;
import java.util.*;
  
class one {
    public void print_1()
    {
        System.out.println("A");
    }
}
  
class two extends one {
    public void print_2() 
    { 
        System.out.println("B");
    }
}
  
class three extends two {
    public void print_3()
    {
        System.out.println("C");
    }
}
  
// Drived class
public class Main {
    public static void main(String[] args)
    {
        three g = new three();
        g.print_1();
        g.print_2();
        g.print_3();
    }
}

Output

A
B
C

3. Hierarchical Inheritance

In Hierarchical Inheritance, one class serves as a superclass (base class) for more than one subclass. In the below image, class A serves as a base class for the derived classes B, C, and D

// Java program to illustrate the
// concept of Hierarchical inheritance

class A {
	public void print_A() { System.out.println("Class A"); }
}

class B extends A {
	public void print_B() { System.out.println("Class B"); }
}

class C extends A {
	public void print_C() { System.out.println("Class C"); }
}

class D extends A {
	public void print_D() { System.out.println("Class D"); }
}

// Driver Class
public class Test {
	public static void main(String[] args)
	{
		B obj_B = new B();
		obj_B.print_A();
		obj_B.print_B();

		C obj_C = new C();
		obj_C.print_A();
		obj_C.print_C();

		D obj_D = new D();
		obj_D.print_A();
		obj_D.print_D();
	}
}

Output

Class A
Class B
Class A
Class C
Class A
Class D

4. Multiple Inheritance (Through Interfaces)

In Multiple inheritances, one class can have more than one superclass and inherit features from all parent classes. Please note that Java, C# does not support multiple inheritances with classes. We can achieve multiple inheritances only through Interfaces. In the image below, Class C is derived from interfaces A and B.

// Java program to illustrate the
// concept of Multiple inheritance
import java.io.*;
import java.lang.*;
import java.util.*;

interface one {
	public void print_A();
}

interface two {
	public void print_B();
}

interface three extends one, two {
	public void print_A();
}
class child implements three {
	@Override public void print_A()
	{
		System.out.println("A");
	}

	public void print_B() 
	{ 
		System.out.println("B");
	}
}

// Drived class
public class Main {
	public static void main(String[] args)
	{
		child c = new child();
		c.print_geek();
		c.print_for();
		c.print_geek();
	}
}

Output

A
B
A

5. Hybrid Inheritance

Hybrid inheritance is a combination of two or more types of inheritance. The combination of multilevel and hierarchical inheritance is an example of Hybrid inheritance.

Method Overriding in C# Inheritance

If the same method is present in both the base class and the derived class, the method in the derived class overrides the method in the base class. This is called method overriding in C#. For example,

using System;

namespace Inheritance {

  // base class
  class Animal { 
    public virtual void eat() {

      Console.WriteLine("I eat food");
    }
  } 
  
  // derived class of Animal 
  class Dog : Animal {

    // overriding method from Animal
    public override void eat() {

      Console.WriteLine("I eat Dog food");
    }     
  }
  class Program {

    static void Main(string[] args) {
      // object of derived class
      Dog labrador = new Dog();

      // accesses overridden method
      labrador.eat();
    }
  }
}

Notice, we have used virtual and override with methods of the base class and derived class respectively. Here,

  • virtual - allows the method to be overridden by the derived class

  • override - indicates the method is overriding the method from the base class

base Keyword in C# Inheritance

In the previous example, we saw that the method in the derived class overrides the method in the base class.

However, what if we want to call the method of the base class as well?

In that case, we use the base keyword to call the method of the base class from the derived class.

using System;

namespace Inheritance {

  // base class
  class Animal { 
    public virtual void eat() {

      Console.WriteLine("Animals eat food.");
    }
  } 
  
  // derived class of Animal 
  class Dog : Animal {

    // overriding method from Animal
    public override void eat() {
      
      // call method from Animal class
      base.eat();
      
      Console.WriteLine("Dogs eat Dog food.");
    }     
  }
  class Program {

    static void Main(string[] args) {

      Dog labrador = new Dog();
      labrador.eat();
    }
  }
}

Output

Animals eat food.
Dogs eat Dog food.

In the above example, the eat() method is present in both the base class Animal and the derived class Dog. Notice the statement,

base.eat();

Here, we have used the base keyword to access the method of Animal class from the Dog class.

The sealed Keyword in C#

If you don't want other classes to inherit from a class, use the sealed keyword:

If you try to access a sealed class, C# will generate an error:

sealed class Vehicle 
{
  ...
}

class Car : Vehicle 
{
  ...
}

The error message will be something like this:

'Car': cannot derive from sealed type 'Vehicle'

What Can Be Done in a Subclass?

In sub-classes we can inherit members as is, replace them, hide them, or supplement them with new members:

  • The inherited fields can be used directly, just like any other fields.

  • We can declare new fields in the subclass that are not in the superclass.

  • The inherited methods can be used directly as they are.

  • We can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it (as in the example above, toString() method is overridden).

  • We can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.

  • We can declare new methods in the subclass that are not in the superclass.

  • We can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.

Advantages Of Inheritance:

  1. Code Reusability: Inheritance allows for code reuse and reduces the amount of code that needs to be written. The subclass can reuse the properties and methods of the superclass, reducing code duplication.

  2. Abstraction: Inheritance allows for the creation of abstract classes that define a common interface for a group of related classes. This promotes abstraction and encapsulation, making the code easier to maintain and extend.

  3. Class Hierarchy: Inheritance allows for the creation of a class hierarchy, which can be used to model real-world objects and their relationships.

  4. Polymorphism: Inheritance allows for polymorphism, which is the ability of an object to take on multiple forms. Subclasses can override the methods of the superclass, which allows them to change their behavior in different ways.

Disadvantages of Inheritance

  1. Complexity: Inheritance can make the code more complex and harder to understand. This is especially true if the inheritance hierarchy is deep or if multiple inheritances are used.

  2. Tight Coupling: Inheritance creates a tight coupling between the superclass and subclass, making it difficult to make changes to the superclass without affecting the subclass.

Conclusion

Let us check some important points from the article are mentioned below:

  • Default superclass: Except Object class, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of the Object class.

  • Superclass can only be one: A superclass can have any number of subclasses. But a subclass can have only one superclass. This is because Java does not support multiple inheritances with classes. Although with interfaces, multiple inheritances are supported by Java.

  • Inheriting Constructors: A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

  • Private member inheritance: A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods(like getters and setters) for accessing its private fields, these can also be used by the subclass.

More reference:

https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/inheritance

Last updated