60-Second Version: Polymorphism = "many forms". Same method name Start() behaves differently for SportsCar vs Sedan. Code treats them all as Car.
1. Two Types of Polymorphism
Compile-time: Method Overloading - same name, different parameters
public void Print(string name) { Console.WriteLine(name); }
public void Print(int id) { Console.WriteLine(id); }
Runtime: Method Overriding - child changes parent behavior
public class Car
{
public virtual void Start() { Console.WriteLine("Car starts"); }
}
public class SportsCar : Car
{
public override void Start() { Console.WriteLine("VROOM!"); }
}
2. The Power: One Variable, Many Types
Car myCar = new SportsCar(); // Car variable, SportsCar object
myCar.Start(); // Output: VROOM! Calls SportsCar version
myCar = new Sedan(); // Same variable, different object
myCar.Start(); // Output: Car starts quietly. Calls Car version
Beginner Trap: Forgetting virtual in parent or override in child. Without both, polymorphism doesn't work. It will call parent version always.
1. Compile-time Polymorphism: Method Overloading
Same method name, different signatures. Compiler picks which one to run based on parameters.
public class Calculator
{
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
public int Add(int a, int b, int c) => a + b + c;
}
Calculator calc = new Calculator();
calc.Add(2, 3); // Calls first method
calc.Add(2.5, 3.5); // Calls second method
2. Runtime Polymorphism: Method Overriding
This is the real power. Requires 3 things: inheritance + virtual + override
public class Car
{
public virtual void Honk() { Console.WriteLine("Beep"); }
public virtual void Start() { Console.WriteLine("Engine starts"); }
}
public class SportsCar : Car
{
public override void Honk() { Console.WriteLine("LOUD BEEP!"); }
public override void Start()
{
base.Start(); // Call parent first
Console.WriteLine("Sports mode activated");
}
}
public class Sedan : Car
{
public override void Honk() { Console.WriteLine("Soft beep"); }
}
3. Using base Keyword
base.Start() calls the parent version. Use it when you want to extend, not replace.
public override void Start()
{
base.Start(); // "Engine starts"
Console.WriteLine("VROOM!"); // Your addition
}
// Output: Engine starts
// VROOM!
4. virtual vs abstract vs new
public class Car
{
public virtual void Start() { } // Has code, child CAN override
public abstract void Stop(); // No code, child MUST override - class must be abstract
}
public class SportsCar : Car
{
public override void Stop() { Console.WriteLine("Screech!"); } // Required
public new void Honk() { Console.WriteLine("Horn"); } // Hides parent, breaks polymorphism
}
Never use new for polymorphism. It hides the method instead of overriding. Car c = new SportsCar(); c.Honk(); would call Car's version.
5. Real-World: Why Use This?
List<Car> parkingLot = new List<Car>();
parkingLot.Add(new SportsCar());
parkingLot.Add(new Sedan());
parkingLot.Add(new Truck());
foreach(Car car in parkingLot)
{
car.Start(); // Each car starts differently, but same code!
}
You write the loop once. Add 10 new car types later - loop never changes. That's the power.
6. C# Rule: Must Have IS-A Relationship
Polymorphism only works with inheritance. SportsCar : Car = OK. SportsCar : Airplane = nonsense. Compiler allows it but logic fails.
No comments yet. Be the first to share your thoughts!