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?
-
Employeeis the base class. -
Manageris the derived class. -
Managerinherits the publicNameproperty andDisplay()method. -
Manageralso defines its ownApproveLeave()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:
-
Call a base-class constructor.
-
Call a base-class method.
-
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 |
|
|
|
|---|---|---|---|
|
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 |
Uses |
|
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. |
Access base members and constructors |
|
6. Constructor execution |
Base constructor body before derived |
|
7. |
Allow overriding, override, hide |
|
8. Method hiding |
|
|
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.