Inheritance is one of the core principles of OOP. It lets you create new classes based on existing ones. The new class inherits all the fields and methods of the original class and can add its own on top.
How Inheritance Works
class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine($"{Name} is eating.");
}
public void Sleep()
{
Console.WriteLine($"{Name} is sleeping.");
}
}
class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} says: Woof!");
}
}
// Using it
Dog rex = new Dog();
rex.Name = "Rex";
rex.Eat(); // Rex is eating. (inherited from Animal)
rex.Sleep(); // Rex is sleeping. (inherited from Animal)
rex.Bark(); // Rex says: Woof! (defined in Dog)
The : symbol means "inherits from". Dog gets everything from
Animal for free โ Name, Eat(), and Sleep() โ and adds its own Bark() method.
The is-a Relationship
Inheritance represents an "is-a" relationship. A Dog is an Animal. A Cat is an Animal. If the relationship does not make sense with "is-a", you should not use inheritance.
- Dog is an Animal โ
- Student is a Person โ
- Car is an Engine โ (a car has an engine, not is an engine)
Overriding Methods
A derived class can change the behavior of inherited methods using the override
keyword:
class Animal
{
public string Name { get; set; }
public virtual void Speak()
{
Console.WriteLine($"{Name} makes a sound.");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} says: Meow!");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} says: Woof!");
}
}
Cat kitty = new Cat();
kitty.Name = "Whiskers";
kitty.Speak(); // Whiskers says: Meow!
Dog puppy = new Dog();
puppy.Name = "Buddy";
puppy.Speak(); // Buddy says: Woof!
The base class method must be marked as virtual to allow overriding. Then
the derived class uses override to provide its own implementation.
Calling the Base Constructor
class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
}
class Student : Person
{
public int GPA { get; set; }
// Call base constructor using : base()
public Student(string name, int gpa) : base(name)
{
GPA = gpa;
}
}
Student s = new Student("Amina", 3);
Console.WriteLine($"{s.Name} has GPA {s.GPA}");
When a derived class constructor runs, it must first initialize the base class. The
: base(name) syntax lets you pass arguments to the base constructor.