← Back to Articles         
Inheritance

Inheritance

Published on 12 Oct 2026     16 min read OOPs
Inheritance

Section 4: Inheritance, Method Overriding & Sealed Classes | 11 Questions | C# / .NET

1. 🔴 What is inheritance, and why is it used in C#?

What is inheritance?

Inheritance is one of the four pillars of Object-Oriented Programming (OOP).

It allows a class (derived/child class) to inherit accessible properties, methods, and behavior from another class (base/parent class).

In C#, inheritance is implemented using the : symbol.

C# example

// Base class
public class Employee
{
    public string Name { get; set; } = "";

    public void Display()
    {
        Console.WriteLine($"Employee: {Name}");
    }
}

// Derived class
public class Manager : Employee
{
    public void ApproveLeave()
    {
        Console.WriteLine("Leave approved");
    }
}

Usage:

Manager manager = new Manager();

manager.Name = "John";
manager.Display();
manager.ApproveLeave();

Output:

Employee: John
Leave approved

How does it work?

  • Employee is the base class.

  • Manager is the derived class.

  • Manager inherits the public Name property and Display() method.

  • Manager also defines its own ApproveLeave() method.

Why is inheritance used?

Advantage

Explanation

Code reusability

Reuses existing base-class functionality

Maintainability

Common logic can be maintained centrally

Extensibility

Derived classes can add new functionality

Polymorphism

Base references can point to derived objects

Code organization

Represents logical is-a relationships

Real-time scenario

In a payroll system, Employee can be the base class, while Manager and Developer inherit common employee details and implement their own bonus calculations.

Interview answer

Inheritance allows a derived class to reuse and extend the functionality of a base class. In C#, it is implemented using the : symbol. It promotes code reusability, maintainability, extensibility, and runtime polymorphism.

 

2. 🔴 What types of inheritance are supported in C#?

C# supports single, multilevel, and hierarchical class inheritance. Multiple and hybrid inheritance involving multiple base classes are not supported directly, but multiple interface implementation is supported.

1. Single inheritance

One derived class inherits from one base class.

Employee
   |
   v
Manager
public class Employee { }

public class Manager : Employee { }

2. Multilevel inheritance

A class inherits from another derived class.

Employee
   |
   v
Manager
   |
   v
SeniorManager
public class Employee { }

public class Manager : Employee { }

public class SeniorManager : Manager { }

SeniorManager inherits accessible functionality from both Manager and Employee.

3. Hierarchical inheritance

Multiple derived classes inherit from the same base class.

        Employee
           |
     +-----+-----+
     |           |
     v           v
  Manager     Developer
public class Employee { }

public class Manager : Employee { }

public class Developer : Employee { }

4. Multiple interface implementation

A class can implement multiple interfaces.

IPrintable       ISavable
    |               |
    +-------+-------+
            |
            v
         Document
public interface IPrintable
{
    void Print();
}

public interface ISavable
{
    void Save();
}

public class Document : IPrintable, ISavable
{
    public void Print() => Console.WriteLine("Print");

    public void Save() => Console.WriteLine("Save");
}

Comparison table

Type

Supported in C#

Explanation

Single

Yes

One class inherits another

Multilevel

Yes

A chain of inherited classes

Hierarchical

Yes

Multiple classes inherit one base

Multiple class

No

Cannot inherit two base classes

Hybrid

Partial

Possible through a combination of class inheritance and interfaces

Interview answer

C# supports single, multilevel, and hierarchical class inheritance. It does not support multiple class inheritance, but a class can implement multiple interfaces. This provides flexibility while avoiding complications associated with inheriting from multiple classes.

 

3. 🔴 Why does C# not support multiple class inheritance?

Explanation

C# does not allow a class to inherit directly from more than one class.

One major reason is to avoid ambiguity and complexity, particularly the diamond problem.

What is the diamond problem?

Consider the following conceptual inheritance structure:

          Class A
          /     \
         v       v
      Class B   Class C
         \       /
          v     v
          Class D

Suppose Class B and Class C both inherit and override a method named Display() from Class A.

If Class D inherits from both classes, which Display() implementation should it use?

This can create ambiguity.

Invalid C# example

public class A
{
    public void Display() { }
}

public class B : A { }

public class C : A { }

// Compilation error
public class D : B, C { }

How does C# solve this?

C# allows multiple interface implementation.

public interface IA
{
    void Display();
}

public interface IB
{
    void Display();
}

public class MyClass : IA, IB
{
    public void Display()
    {
        Console.WriteLine("Display");
    }
}

The single public method satisfies both interface contracts.

If different behavior is required, explicit interface implementation can be used.

Interview answer

C# does not support multiple class inheritance primarily to avoid ambiguity and complexity, including the diamond problem. Instead, C# allows a class to implement multiple interfaces. This enables multiple contracts without allowing multiple base-class inheritance.

 

4. 🔴 What is the difference between inheritance and composition?

Inheritance

Inheritance represents an IS-A relationship.

For example, a Manager is an Employee.

Composition

Composition represents a HAS-A relationship.

For example, an Employee has an Address.

C# example: Inheritance

public class Employee
{
    public string Name { get; set; } = "";
}

public class Manager : Employee
{
    public void ApproveLeave()
    {
        Console.WriteLine("Approved");
    }
}

Manager IS-A Employee.

C# example: Composition

public class Address
{
    public string City { get; set; } = "";
}

public class Employee
{
    public string Name { get; set; } = "";

    public Address Address { get; set; } = new();
}

Usage:

Employee emp = new Employee
{
    Name = "John",
    Address = new Address
    {
        City = "Chennai"
    }
};

Console.WriteLine(emp.Address.City);

Employee HAS-A Address.

Comparison table

Inheritance

Composition

IS-A relationship

HAS-A relationship

Uses :

Uses object references

Reuses base-class behavior

Reuses contained objects

Creates tighter coupling

Usually provides more flexibility

Supports overriding

Supports delegation

Example: Manager → Employee

Employee → Address

Real-time ASP.NET Core example

Composition is frequently used with dependency injection.

public class EmployeeService
{
    private readonly IEmployeeRepository _repository;

    public EmployeeService(IEmployeeRepository repository)
    {
        _repository = repository;
    }
}

Here, EmployeeService uses an IEmployeeRepository dependency rather than inheriting from a repository.

This is an example of composition through dependency injection.

Interview answer

Inheritance represents an IS-A relationship, while composition represents a HAS-A relationship. Inheritance reuses functionality through a base class, whereas composition builds functionality by combining objects. Composition is often preferred in enterprise applications because it reduces coupling and makes components easier to replace and test.

 

5. 🔴 What is the purpose of the base keyword?

Explanation

The base keyword is used inside a derived class to access members of its base class.

It is mainly used to:

  1. Call a base-class constructor.

  2. Call a base-class method.

  3. Access a base-class property or field.

C# example

public class Employee
{
    public Employee(string name)
    {
        Console.WriteLine($"Employee: {name}");
    }

    public virtual void Display()
    {
        Console.WriteLine("Base Display");
    }
}

public class Manager : Employee
{
    public Manager(string name) : base(name)
    {
        Console.WriteLine("Manager Constructor");
    }

    public override void Display()
    {
        base.Display();

        Console.WriteLine("Manager Display");
    }
}

Usage:

Manager manager = new Manager("John");

manager.Display();

Output:

Employee: John
Manager Constructor
Base Display
Manager Display

Explanation

  • base(name) calls the base-class constructor.

  • base.Display() calls the base-class implementation.

  • The derived class can extend existing functionality instead of replacing it completely.

Interview answer

The base keyword is used to access base-class members from a derived class. It can call a base constructor, invoke a base method, or access a base property. It is useful when derived classes need to reuse or extend base-class functionality.

 

6. 🔴 What happens when a derived class and base class have constructors?

Explanation

When a derived-class object is created, constructors execute in a specific order.

The base-class constructor body executes before the derived-class constructor body.

C# example

public class Employee
{
    public Employee()
    {
        Console.WriteLine("Employee Constructor");
    }
}

public class Manager : Employee
{
    public Manager()
    {
        Console.WriteLine("Manager Constructor");
    }
}

Usage:

Manager manager = new Manager();

Output:

Employee Constructor
Manager Constructor

Execution flow

new Manager()
      |
      v
Employee Constructor
      |
      v
Manager Constructor
      |
      v
Object Ready

What if the base class has a parameterized constructor?

public class Employee
{
    public Employee(string name)
    {
        Console.WriteLine(name);
    }
}

public class Manager : Employee
{
    public Manager(string name) : base(name)
    {
        Console.WriteLine("Manager created");
    }
}

The derived constructor explicitly calls the base constructor using base(name).

If the base class has no accessible parameterless constructor, the derived constructor must call an appropriate accessible base constructor.

Interview answer

When a derived-class object is created, the base-class constructor body executes before the derived-class constructor body. If the base class has a parameterized constructor, the derived class can call it using base(). This ensures that base-class initialization is completed before the derived constructor body executes.

 

7. 🔴 What is the difference between virtual, override, and new keywords?

Explanation

These keywords are used in inheritance to control method behavior.

  • virtual – Allows a method to be overridden.

  • override – Provides a new implementation of an inherited virtual or abstract method.

  • new – Hides an inherited member instead of overriding it.

C# example

public class Employee
{
    public virtual void Display()
    {
        Console.WriteLine("Employee Display");
    }
}

public class Manager : Employee
{
    public override void Display()
    {
        Console.WriteLine("Manager Display");
    }
}

public class Developer : Employee
{
    public new void Display()
    {
        Console.WriteLine("Developer Display");
    }
}

Usage

Employee emp1 = new Manager();
emp1.Display();

Employee emp2 = new Developer();
emp2.Display();

Developer dev = new Developer();
dev.Display();

Output:

Manager Display
Employee Display
Developer Display

Why do the results differ?

For override, C# selects the implementation based on the actual runtime object type.

For new, the selected member depends on the compile-time reference type because the derived method hides the inherited method.

Comparison table

Feature

virtual

override

new

Purpose

Allow overriding

Replace inherited virtual implementation

Hide inherited member

Used in

Base or derived class

Derived class

Derived class

Method body

Required

Required for concrete override

Required for concrete method

Runtime polymorphism

Enables

Participates

Does not override base dispatch

Requires inherited virtual member

No

Yes, virtual/abstract/override

No

Common usage

Customizable base behavior

Specialized derived behavior

Intentional member hiding

Interview answer

virtual allows a method to be overridden, override provides a new implementation of a virtual or abstract method, and new hides an inherited member. Overriding supports runtime polymorphism, while method hiding selects members based on the compile-time reference type.

 

8. 🟡 What is method hiding, and how does it differ from method overriding?

Method hiding

Method hiding occurs when a derived class declares a member with the same name and signature as an inherited member, using the new keyword.

Method overriding

Method overriding occurs when a derived class provides a different implementation of an inherited virtual or abstract method using override.

C# example

public class Parent
{
    public virtual void Show()
    {
        Console.WriteLine("Parent Show");
    }
}

public class ChildOverride : Parent
{
    public override void Show()
    {
        Console.WriteLine("Child Override");
    }
}

public class ChildHide : Parent
{
    public new void Show()
    {
        Console.WriteLine("Child Hide");
    }
}

Usage:

Parent p1 = new ChildOverride();
p1.Show();

Parent p2 = new ChildHide();
p2.Show();

ChildHide c = new ChildHide();
c.Show();

Output:

Child Override
Parent Show
Child Hide

Comparison table

Method overriding

Method hiding

Uses override

Uses new

Requires overridable base member

Does not require virtual base member

Runtime dispatch

Compile-time member selection

Supports runtime polymorphism

Does not override base polymorphism

Base reference calls derived override

Base reference calls base implementation

Interview answer

Method overriding replaces the implementation of an inherited virtual method and supports runtime polymorphism. Method hiding declares a new member with the same name using new. In method hiding, the selected member depends on the reference type rather than simply the runtime object type.

 

9. 🟡 Can private, static, and sealed methods be overridden?

Explanation

No. Private, static, and sealed methods cannot be overridden.

However, the reasons are different.

1. Private methods

Private methods are not accessible to derived classes as inherited overridable members.

public class Parent
{
    private void Display()
    {
        Console.WriteLine("Parent");
    }
}

A derived class can declare its own Display() method, but it does not override the private base method.

2. Static methods

Static methods belong to the type rather than an instance and cannot participate in virtual instance-method overriding.

public class Parent
{
    public static void Display()
    {
        Console.WriteLine("Parent");
    }
}

public class Child : Parent
{
    public new static void Display()
    {
        Console.WriteLine("Child");
    }
}

Static methods can be hidden, but not overridden.

3. Sealed override methods

A method can be declared sealed override to prevent further overriding.

public class Parent
{
    public virtual void Display()
    {
        Console.WriteLine("Parent");
    }
}

public class Child : Parent
{
    public sealed override void Display()
    {
        Console.WriteLine("Child");
    }
}

public class GrandChild : Child
{
    // Cannot override Display() again
}

Comparison table

Method type

Can override?

Reason

Private

No

Not inherited as an accessible overridable member

Static

No

Not an instance virtual method

Sealed override

No

Further overriding is explicitly blocked

Virtual

Yes

Designed to allow overriding

Abstract

Yes

Requires implementation in concrete derived classes

Interview answer

Private, static, and sealed override methods cannot be overridden. Private methods are not accessible for overriding, static methods do not support instance polymorphism, and sealed overrides explicitly prevent further overriding. Only appropriate virtual, abstract, or unsealed override methods can be overridden.

 

10. 🟡 What is a sealed class, and when should you use it?

What is a sealed class?

A sealed class is a class that cannot be inherited by another class.

It is declared using the sealed keyword.

C# example

public sealed class SecurityHelper
{
    public void Validate()
    {
        Console.WriteLine("Validated");
    }
}

Usage:

SecurityHelper helper = new SecurityHelper();
helper.Validate();

A sealed class can be instantiated normally.

However, the following is invalid:

// Compilation error
public class CustomHelper : SecurityHelper
{
}

Why use sealed classes?

Advantage

Explanation

Prevent inheritance

Stops subclasses from extending or altering behavior through inheritance

Design control

Communicates that the class is not intended as a base class

Maintainability

Reduces inheritance-related complexity

Potential optimization

May enable some runtime optimizations

Predictability

Prevents subclass-specific changes to behavior

Real-time scenario

A utility or domain implementation that is not designed for inheritance can be sealed.

public sealed class TaxCalculator
{
    public decimal Calculate(decimal amount)
    {
        return amount * 0.18m;
    }
}

Important interview point

A sealed class is not automatically immutable or secure.

It only prevents inheritance. Its properties and methods may still modify state.

Also, a sealed class can implement interfaces.

public interface ICalculator
{
    decimal Calculate(decimal amount);
}

public sealed class TaxCalculator : ICalculator
{
    public decimal Calculate(decimal amount)
    {
        return amount * 0.18m;
    }
}

Interview answer

A sealed class is declared using the sealed keyword and cannot be inherited. It is used when a class is not intended to be extended, helping control inheritance and maintain predictable behavior. Sealed classes can still be instantiated and implement interfaces.

 

11. 🟡 What is the constructor and destructor execution order in inheritance?

Constructor execution order

In C#, constructor bodies execute from the base class to the derived class.

C# example

public class A
{
    public A()
    {
        Console.WriteLine("Constructor A");
    }
}

public class B : A
{
    public B()
    {
        Console.WriteLine("Constructor B");
    }
}

public class C : B
{
    public C()
    {
        Console.WriteLine("Constructor C");
    }
}

Usage:

C obj = new C();

Output:

Constructor A
Constructor B
Constructor C

Constructor execution flow

Create Object C
      |
      v
Constructor A
      |
      v
Constructor B
      |
      v
Constructor C
      |
      v
Object Ready

Destructor (finalizer) execution order

C# uses finalizers, written with destructor-like syntax:

public class A
{
    ~A()
    {
        Console.WriteLine("Finalizer A");
    }
}

public class B : A
{
    ~B()
    {
        Console.WriteLine("Finalizer B");
    }
}

When a B object is finalized, its finalizer runs before the base finalizer.

Conceptually:

Finalizer B
     |
     v
Finalizer A

However, finalization is nondeterministic. The garbage collector decides when an eligible object is finalized, and finalization is not guaranteed to occur before the process terminates.

Constructor vs finalizer comparison

Constructor

Finalizer

Initializes an object

Performs finalization cleanup

Executes during object creation

Executes when GC finalizes an eligible object

Base constructor body first

Derived finalizer before base finalizer

Predictable execution during normal construction

Timing is nondeterministic

Can accept parameters

Cannot accept parameters

Commonly used

Rarely needed

Important real-time .NET point

For resources such as database connections, streams, and file handles, use IDisposable or IAsyncDisposable rather than relying on finalizers.

using var connection = new SqlConnection(connectionString);

await connection.OpenAsync();

// Database operations

The using statement ensures disposal when the scope exits, including when an exception occurs.

Interview answer

In C#, base-class constructor bodies execute before derived-class constructor bodies. For finalizers, the derived-class finalizer runs before the base-class finalizer when finalization occurs. However, finalization timing is controlled by the garbage collector and is not guaranteed. For deterministic resource cleanup, IDisposable is preferred.

 

Quick Interview Revision – All 11 Questions

Question

Key points to remember

1. Inheritance

IS-A relationship, reuse and extend behavior

2. Types of inheritance

Single, multilevel, hierarchical; multiple interfaces

3. Multiple class inheritance

Not supported; avoids ambiguity

4. Inheritance vs Composition

IS-A vs HAS-A

5. base keyword

Access base members and constructors

6. Constructor execution

Base constructor body before derived

7. virtual, override, new

Allow overriding, override, hide

8. Method hiding

new vs override

9. Private/static/sealed methods

Cannot override

10. Sealed class

Prevent class inheritance

11. Constructor/finalizer order

Base → Derived / Derived → Base

Additional interview points for Senior .NET Developers

1. Can a derived class override a virtual method and call the base implementation?

Yes, using base.MethodName().

2. Can a normal class contain virtual methods?

Yes. Both normal and abstract classes can contain virtual methods.

3. Can an abstract class inherit another abstract class?

Yes. It can implement or defer inherited abstract members.

4. Can a sealed class implement multiple interfaces?

Yes. Sealing prevents class inheritance, not interface implementation.

5. Can constructors be inherited or overridden?

No. Constructors are not inherited as ordinary members and cannot be overridden. A derived constructor can call a base constructor.

6. Which is preferred in modern ASP.NET Core: inheritance or composition?

Composition is often preferred for services and dependencies because it supports loose coupling, dependency injection, and testability. Inheritance remains appropriate for genuine IS-A relationships and shared base behavior.

Interview priority: Questions 4, 5, 6, 7, 8, and 9 are especially important for Senior .NET Developer and Technical Lead interviews because they test practical understanding of inheritance, runtime polymorphism, and application design.

← Back to Articles