Day 6: Inheritance, Polymorphism, & Interfaces
Welcome to Day 6. We continue our OOP journey by seeing how objects talk to and build upon each other.
If you have a Dog class and a Cat class, they probably share a lot in common (Age, Name, Eat()). Instead of writing that code twice, we can use Inheritance.
Inheritance
A class can inherit properties and methods from a base (parent) class using the : syntax. Unlike C++, C# only supports single inheritance (a class can only have one parent class).
// Base Class
public class Animal
{
public string Name { get; set; }
// Virtual means child classes are ALLOWED to override it
public virtual void Speak()
{
Console.WriteLine("Generic animal sound");
}
}
// Derived Class
public class Dog : Animal
{
// Override replaces the base implementation
public override void Speak()
{
Console.WriteLine("Woof!");
}
}
Now, Dog automatically has a Name property!
Polymorphism
Because Dog IS an Animal, we can treat it like one. This is huge when dealing with collections.
List<Animal> myAnimals = new List<Animal>
{
new Dog { Name = "Buddy" },
new Cat { Name = "Whiskers" },
new Bird { Name = "Tweety" }
};
foreach (var animal in myAnimals)
{
animal.Speak(); // Outputs Woof, Meow, Tweet (calls the specific override!)
}
Abstract Classes
Sometimes, it makes no sense to instantiate the base class itself. Have you ever seen a generic “Animal” walking down the street? No, you see a specific Cat or Dog.
You can mark a class as abstract. This means:
- It cannot be instantiated (
new Animal()will throw an error). - It can contain
abstractmethods, which force derived classes to implement them.
public abstract class Shape
{
// Every child MUST write the code for this!
public abstract double CalculateArea();
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double CalculateArea() => Math.PI * Radius * Radius;
}
Interfaces (The Contract)
An Interface is purely a contract. It says, “Any class that implements me MUST have these properties and methods.” It contains no implementation itself (usually).
Interfaces are crucial in ASP.NET Core for Dependency Injection (which we’ll cover later!). By convention, interface names always start with an I.
public interface ILogger
{
void LogInfo(string message);
void LogError(string error);
}
// ConsoleLogger agrees to the ILogger contract
public class ConsoleLogger : ILogger
{
public void LogInfo(string message) => Console.WriteLine($"INFO: {message}");
public void LogError(string error) => Console.WriteLine($"ERROR: {error}");
}
// Classes can implement MULTIPLE interfaces!
public class SuperLogger : ILogger, IEmailSender
{ ... }
Challenge for Day 6
- Create an
IVehicleinterface with aStartEngine()method. - Create an abstract
Carclass that implementsIVehicleand adds aNumberOfDoorsproperty. - Create a concrete
SportsCarclass that inherits fromCar.
Tomorrow: Collections & LINQ!