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.