C# Inheritance

C# Inheritance

In our previous article, we have seen C# Class tutorial, this is a continuation of that. Here we will cover c# class inheritance.

It is an OOPS concept, where we can make a class inherit from another class thereby utilizing the features of a parent class. Inheritance helps us to reuse the features available in the parent class and which helps to increase productivity. Also, the code written is very much organized.  

Types of Inheritance

Inheritance can be of different types. Below are the common types of inheritance in different programming languages.

  • Single
  • Multi-Level
  • Multiple
  • Hierarchical
Inheritance types

For example, let us look into the below example. It is common in a company employee is of type of permanent and contract. Let’s assume contract employees paid an hourly basis. But both Permanent and Contract employee will be having Name and Age properties. So we can make a Parent class with the name “Employee” which will be having Name and Age property. Contract and Permanent Employee class derive from the common employee class.

C# Inheritance
using System;
namespace MyTestConsoleApp
{
    class Practice
    {
        public class Employee
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        public class PermanentEmployee : Employee
        {
            public readonly int salary;
            public PermanentEmployee(int salary)
            {
                this.salary = salary;
            }
        }

        public class ContractEmployee : Employee
        {
            public readonly int hourlypay;
            public ContractEmployee(int hourlypay)
            {
                this.hourlypay = hourlypay;
            }
        }

        public static void Main(string[] args)
        {
            PermanentEmployee pe = new PermanentEmployee(5000);
            ContractEmployee ce = new ContractEmployee(15);

            pe.Name = "Ram";
            pe.Age = 30;
            ce.Name = "John";
            ce.Age = 25;

            Console.WriteLine(string.Format("Permanent Employee : Name ={0},Age ={ 1},Salary ={ 2}", pe.Name, pe.Age, pe.salary));
            Console.WriteLine(string.Format("Contract Employee : Name ={0},Age ={ 1},Houry Pay = { 2 }", ce.Name, ce.Age, ce.hourlypay));


        }

    }
}

In inheritance private members, finalizers, static constructors are not inherited. Private members are visible to the derived class only when the derived class nested in their base class. Public, protected, internal members, etc are accessible in the derived class.

C# does not support multiple inheritances (because of the diamond problem) however supports multiple interfaces.

Inheritance in C# Constructor Execution Order

When the instance of a derived class object is created, by default base class default constructor is called. We can explicitly specify which base class constructor needs to be called using the base keyword. When we have a static constructor in the base and derived class, during instantiation of the derived class,’ first derived class static constructor and followed by parent class static constructor is called. But in the case of a nonstatic constructor, the first base class constructor and followed by a derived class constructor is called.   The below example explains the order of execution of the constructor.

using System;
namespace MyTestConsoleApp
{
    class Practice
    {
        //base class
        public class Employee
        {
            public string Name { get; set; }
            public int Age { get; set; }

            //static constructor
            //Execution Order: 2
            static Employee()
            {
                Console.WriteLine("Parent static Constructor Called");
            }

            //Default constructor
            //Execution Order: 6
            public Employee()
            {
                Console.WriteLine("Parent Default Constructor Called");
            }

            //Execution Order: 3
            public Employee(string Name, int Age)
            {
                Console.WriteLine("Parent Constructor with Args Called");

                this.Name = Name;
                this.Age = Age;
            }
        }

        //Derived class 1
        public class PermanentEmployee : Employee
        {
            public readonly int salary;

            //static constructor
            //Execution Order: 1
            static PermanentEmployee()
            {
                Console.WriteLine("Derived 1 static Called");
            }

            //Derived Class constructor
            //Explicitly specifying which base class constructor needs to be called
            ////Execution Order: 4
            public PermanentEmployee(string Name, int Age, int salary) : base(Name, Age)
            {
                Console.WriteLine("Derived 1 Constructor Called");
                this.salary = salary;
            }
        }

        //Derived class 2
        public class ContractEmployee : Employee
        {
            public readonly int hourlypay;

            //static constructor
            //Execution Order: 5
            static ContractEmployee()
            {
                Console.WriteLine("Derived 2 static Constructor Called");
            }

            //Derived Class constructor
            //Execution Order: 7
            public ContractEmployee(int hourlypay)
            {

                Console.WriteLine("Derived 2 Constructor Called");
                this.hourlypay = hourlypay;
            }
        }

        public static void Main(string[] args)
        {
            PermanentEmployee pe = new PermanentEmployee("Ram", 30, 5000);
            ContractEmployee ce = new ContractEmployee(15);

            ce.Name = "John";
            ce.Age = 25;

            Console.WriteLine(string.Format("Permanent Employee : Name ={0},Age ={1},Salary ={2}", pe.Name, pe.Age, pe.salary));
            Console.WriteLine(string.Format("Contract Employee : Name ={0},Age ={1},Houry Pay = {2}", ce.Name, ce.Age, ce.hourlypay));



        }

    }
}

When you run this below will  be the output

C# Inheritance

Base and Derived class Reference Variable

When we have a method in both base class and derived class that shares a common name, there will be an ambiguity about which method will be executed. When a derived class object is assigned to the derived class reference variable derived class method will be executed. Similarly when the base class object is assigned to the base class reference variable base class method will be called.

In inheritance we can assign instance of a derived class to reference of base class.In this case normally base class is method is called, but by using casting and other techniques we can execute derived class method with base class reference variable.

Below example explains all the scenario.

using System;
namespace MyTestConsoleApp
{
public class Parent
{
public void Greet()
{
Console.WriteLine("Hello from Parent");
}
}

public class Derived:Parent
{
public new void Greet()
{
Console.WriteLine("Hello from Derived");
}
}

class Practice
{
public static void Main(string[] args)
{
Derived d1 = new Derived();
d1.Greet();
//Hello from Derived

Parent p1 = new Parent();
p1.Greet();
//Hello from Parent

Parent p2 = new Derived();
p2.Greet();
//Hello from Parent

Parent p3 = new Derived();
((Derived)p3).Greet();
//Hello from Derived

}

}
}

C# Multiple Inheritance

C# does not support multiple class inheritance as it may lead to a problem where the same features inherited multiple times. But the same functionality can be achieved using multiple interface implementation.

Let us look at the below example. We have two interfaces I1 and I2. Class C1 and C2 inherit interfaces I1 and I2 respectively. Assume that we want to have another class D which should have the functionality of both C1 and C2. Since C# does not allow us to inherit two classes we will inherit two interfaces I1 and I2.

Class D provided the implementation for the interface methods by creating instances of the class C1 and C2.

using System;
namespace Learn
{
    interface I1
    {
        void Method1();
    }
    class C1 : I1
    {
        public void Method1()
        {
            Console.WriteLine("Method1");
        }
    }

    interface I2
    {
        void Method2();
    }
    class C2 : I2
    {
        public void Method2()
        {
            Console.WriteLine("Method2");
        }
    }

    class D : I1, I2
    {
        C1 c1 = new C1();
        C2 c2 = new C2();
        public void Method1()
        {
            c1.Method1();
        }
        public void Method2()
        {
            c2.Method2();

        }
    }
    class Practice
    {
        public static void Main(string[] args)
        {
            D d = new D();
            d.Method1();//Method1
            d.Method2();//Method2
        }
    }
}

Leave a Reply