Inheritance is one of the fundamental concepts of Object-Oriented Programming (OOP) in C#.
It allows a child class (derived class) to inherit members (fields, properties, and methods) from a parent class (base class).
Inheritance helps in code reusability, modular design, and maintainability.
This tutorial covers:
- What is Inheritance?
- Creating a Base Class and Derived Class
- Access Modifiers in Inheritance
- Using base Keyword to Call Base Class Members
- Method Overriding and Virtual Methods
- Sealed Classes and Sealed Methods
- Abstract Classes and Abstract Methods
- Best Practices for Using Inheritance
1. What is Inheritance?
Inheritance allows a child class to use the methods, fields, and properties of a parent class. It helps in code reuse and reduces redundancy.
Example of Inheritance
class Animal // Base class (Parent)
{
public void Eat()
{
Console.WriteLine("Eating...");
}
}
class Dog : Animal // Derived class (Child)
{
public void Bark()
{
Console.WriteLine("Barking...");
}
}
class Program
{
static void Main()
{
Dog myDog = new Dog();
myDog.Eat(); // Inherited from Animal
myDog.Bark(); // Defined in Dog
}
}
Output:
Eating... Barking...
- Dog inherits from Animal, so it can use the Eat() method.
- Dog also defines its own Bark() method.
2. Creating a Base Class and Derived Class
To create inheritance:
- Define a base class with common functionality.
- Create a derived class using the : symbol.
Example: Base Class and Derived Class
class Vehicle
{
public int Speed = 0;
public void Start()
{
Console.WriteLine("Vehicle started.");
}
}
class Car : Vehicle
{
public void Accelerate()
{
Speed += 10;
Console.WriteLine($"Car is now running at {Speed} km/h.");
}
}
class Program
{
static void Main()
{
Car myCar = new Car();
myCar.Start(); // Inherited from Vehicle
myCar.Accelerate(); // Defined in Car
}
}
3. Access Modifiers in Inheritance
Access modifiers control how members of the base class are accessed in derived classes.
| Modifier | Accessible in Derived Class? | Accessible Outside Class? |
|---|---|---|
| public | Yes | Yes |
| protected | Yes | No |
| private | No | No |
| internal | Yes (within the same assembly) | No |
Example: Using protected for Inheritance
class Animal
{
protected void Sleep() // Accessible only in derived classes
{
Console.WriteLine("Sleeping...");
}
}
class Dog : Animal
{
public void Rest()
{
Sleep(); // Can access protected method
}
}
class Program
{
static void Main()
{
Dog myDog = new Dog();
myDog.Rest(); // Calls inherited method
}
}
4. Using base Keyword to Call Base Class Members
The base keyword allows a derived class to access the parent class constructor, methods, and fields.
Example: Calling Base Class Constructor
class Animal
{
public Animal()
{
Console.WriteLine("Animal constructor called.");
}
}
class Dog : Animal
{
public Dog() : base() // Calls base class constructor
{
Console.WriteLine("Dog constructor called.");
}
}
class Program
{
static void Main()
{
Dog myDog = new Dog();
}
}
Output:
Animal constructor called. Dog constructor called.
- base() calls the base class constructor before executing the child constructor.
5. Method Overriding and Virtual Methods
A derived class can override a base class method using the override keyword if the base class method is marked as virtual.
Example: Overriding a Method
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound.");
}
}
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog barks.");
}
}
class Program
{
static void Main()
{
Dog myDog = new Dog();
myDog.MakeSound(); // Calls overridden method
}
}
Output:
Dog barks.
- The base class method is marked as virtual.
- The derived class method uses override to provide a new implementation.
6. Sealed Classes and Sealed Methods
A sealed class prevents inheritance.
Example: Using sealed to Prevent Inheritance
sealed class FinalClass
{
public void Display()
{
Console.WriteLine("This class cannot be inherited.");
}
}
// class AnotherClass : FinalClass {} // ERROR: Cannot inherit from sealed class
A sealed method prevents overriding in derived classes.
Example: Sealing a Method
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound.");
}
}
class Dog : Animal
{
public sealed override void MakeSound()
{
Console.WriteLine("Dog barks.");
}
}
// class Bulldog : Dog { public override void MakeSound() {} } // ERROR: Cannot override sealed method
7. Abstract Classes and Abstract Methods
An abstract class cannot be instantiated and is meant to be inherited.
Example: Abstract Class with Abstract Method
abstract class Animal
{
public abstract void MakeSound(); // No implementation
public void Sleep()
{
Console.WriteLine("Sleeping...");
}
}
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog barks.");
}
}
class Program
{
static void Main()
{
Dog myDog = new Dog();
myDog.MakeSound(); // Must be implemented by derived class
myDog.Sleep(); // Inherited from abstract class
}
}
- abstract methods must be implemented in derived classes.
- abstract classes can contain both abstract and concrete methods.
8. Best Practices for Using Inheritance
Use Inheritance for Code Reusability
class Employee
{
public string Name;
public void Work()
{
Console.WriteLine("Employee working...");
}
}
class Manager : Employee
{
public void Manage()
{
Console.WriteLine("Managing team...");
}
}
- Avoid code duplication by reusing common functionality.
Use protected Instead of private for Base Class Members
class Animal
{
protected string species; // Accessible in derived classes
}
Use override for Custom Behavior
class Parent
{
public virtual void Show() { Console.WriteLine("Parent Show"); }
}
class Child : Parent
{
public override void Show() { Console.WriteLine("Child Show"); }
}
Use sealed When Further Inheritance is Not Needed
sealed class FinalClass { }
Conclusion
- Inheritance enables code reuse and creates a hierarchy of classes.
- Use base to access parent class members.
- Method overriding allows customization of behavior in derived classes.
- Use sealed to restrict inheritance and abstract to enforce implementation.
- Best practices ensure maintainability and efficient code design.
