🏰 The Kingdom of Classes: Inheritance & Polymorphism
Once upon a time, in the land of C#, there lived a powerful concept called Object-Oriented Programming…
🌳 The Family Tree: What is Inheritance?
Imagine you have a family. Your parents gave you some traits—maybe your dad’s eyes or your mom’s smile. You didn’t have to earn these traits; you were born with them!
Inheritance in C# works the same way.
A child class (also called derived class) automatically gets all the stuff from its parent class (also called base class). No extra work needed!
Simple Example
Think of it like this:
- Animal is the parent (base class)
- Dog is the child (derived class)
- Dog automatically knows how to
Eat()because Animal knows how!
class Animal
{
public void Eat()
{
Console.WriteLine("Yum yum!");
}
}
class Dog : Animal
{
public void Bark()
{
Console.WriteLine("Woof!");
}
}
The : symbol means “inherits from.” So Dog : Animal means “Dog inherits from Animal.”
graph TD A[🐾 Animal] --> B[🐕 Dog] A --> C[🐱 Cat] A --> D[🐦 Bird]
Why is this amazing?
- Write code once, use it everywhere!
- Dog can
Eat()ANDBark() - Less typing, fewer bugs, happier you!
📞 Calling Home: The base Keyword
Sometimes, a child wants to call their parent. In C#, we use base for this!
What base Does
| Use Case | What It Does |
|---|---|
base.MethodName() |
Calls parent’s method |
base(args) |
Calls parent’s constructor |
Example: Calling Parent Constructor
class Animal
{
public string Name;
public Animal(string name)
{
Name = name;
}
}
class Dog : Animal
{
public Dog(string name) : base(name)
{
// Dog calls Animal's
// constructor first!
}
}
Example: Calling Parent Method
class Animal
{
public virtual void Speak()
{
Console.WriteLine("Some sound");
}
}
class Dog : Animal
{
public override void Speak()
{
base.Speak(); // Call parent first
Console.WriteLine("Woof!");
}
}
Think of it like: Calling mom before making a big decision! 📱
🎭 Method Overriding: Same Name, Different Dance
Imagine every animal makes a sound. But a dog says “Woof!” while a cat says “Meow!” They’re all doing the same action (Speak) but in their own special way.
This is method overriding!
The Magic Words
virtual= “Child, you CAN change this if you want”override= “I’m changing what my parent did”
class Animal
{
public virtual void Speak()
{
Console.WriteLine("...");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof!");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("Meow!");
}
}
graph TD A[Animal: Speak = '...'] A --> B[Dog: Speak = 'Woof!'] A --> C[Cat: Speak = 'Meow!']
The result:
Animal myDog = new Dog();
myDog.Speak(); // Output: Woof!
Even though myDog is typed as Animal, it barks like a Dog! Magic! ✨
🎪 Shadowing with new: The Imposter
Sometimes you want to hide the parent’s method completely, not change it. This is called shadowing or hiding.
Use the new keyword (different from creating objects!).
Override vs Shadow
| Feature | override |
new (shadow) |
|---|---|---|
| Parent must use | virtual |
Nothing needed |
| Behavior | Replaces | Hides |
| Polymorphism | ✅ Works | ❌ Doesn’t work |
Example
class Animal
{
public void Sleep()
{
Console.WriteLine("Zzz...");
}
}
class Cat : Animal
{
public new void Sleep()
{
Console.WriteLine("Cat nap!");
}
}
The tricky part:
Cat myCat = new Cat();
myCat.Sleep(); // "Cat nap!"
Animal myAnimal = myCat;
myAnimal.Sleep(); // "Zzz..." 😱
With new, the type of the variable decides which method runs. With override, the actual object decides.
🌟 Virtual and Abstract Methods
These are the two magic words for letting children customize behavior.
virtual = Optional Change
“Hey child, you can change this, but you don’t have to.”
class Bird
{
public virtual void Fly()
{
Console.WriteLine("Flap flap!");
}
}
class Penguin : Bird
{
public override void Fly()
{
Console.WriteLine("I can't fly! 🐧");
}
}
abstract = Must Change
“Hey child, you MUST implement this. I don’t even know how to do it myself!”
abstract class Shape
{
public abstract double GetArea();
// No body! Child MUST provide one.
}
class Circle : Shape
{
public double Radius;
public override double GetArea()
{
return 3.14 * Radius * Radius;
}
}
| Keyword | Has Body? | Child Must Override? |
|---|---|---|
virtual |
✅ Yes | ❌ Optional |
abstract |
❌ No | ✅ Required |
🏗️ Abstract Classes: The Blueprint
An abstract class is like a blueprint for a house. You can’t live in a blueprint—you need to build the actual house first!
Rules of Abstract Classes
- Cannot create objects directly
- Can have abstract methods (no body)
- Can have regular methods (with body)
- Child must implement all abstract methods
abstract class Vehicle
{
public string Brand;
// Abstract - child must define
public abstract void Start();
// Regular - child inherits this
public void Stop()
{
Console.WriteLine("Stopped!");
}
}
class Car : Vehicle
{
public override void Start()
{
Console.WriteLine("Vroom vroom!");
}
}
graph TD A["🚗 Vehicle #40;abstract#41; ━━━━━━━━━━ Brand abstract Start#40;#41; Stop#40;#41;"] A --> B["🚙 Car ━━━━━━━━━━ Start#40;#41; = 'Vroom!'"] A --> C["🏍️ Motorcycle ━━━━━━━━━━ Start#40;#41; = 'Brum!'"]
Why use abstract classes?
- Force all children to have certain methods
- Share common code
- Create a “contract” for the family
🎭 Polymorphism: Many Forms, One Name
Poly = many, morph = forms. Polymorphism means “many forms.”
It’s like a TV remote. You press “Power” and:
- Your TV turns on
- Your sound bar turns on
- Your gaming console turns on
Same button, different devices, different actions!
Polymorphism in Action
Animal[] zoo = new Animal[3];
zoo[0] = new Dog();
zoo[1] = new Cat();
zoo[2] = new Bird();
foreach (Animal a in zoo)
{
a.Speak(); // Each speaks differently!
}
Output:
Woof!
Meow!
Chirp!
One loop, many behaviors! 🎉
Real-World Example
abstract class PaymentMethod
{
public abstract void Pay(decimal amount);
}
class CreditCard : PaymentMethod
{
public override void Pay(decimal amount)
{
Console.WriteLine(quot;Card charged: ${amount}");
}
}
class PayPal : PaymentMethod
{
public override void Pay(decimal amount)
{
Console.WriteLine(quot;PayPal sent: ${amount}");
}
}
// Works with ANY payment method!
void Checkout(PaymentMethod method)
{
method.Pay(99.99m);
}
🔒 Sealed Classes and Methods: The Final Word
Sometimes you want to say: “Nobody can change this anymore!”
That’s what sealed does.
Sealed Class
No one can inherit from a sealed class.
sealed class FinalBoss
{
public void Attack()
{
Console.WriteLine("Ultimate attack!");
}
}
// ERROR! Cannot inherit from sealed class
class SuperBoss : FinalBoss { }
Sealed Method
In a child class, you can seal an overridden method to prevent grandchildren from overriding it again.
class Animal
{
public virtual void Breathe()
{
Console.WriteLine("Inhale...");
}
}
class Mammal : Animal
{
public sealed override void Breathe()
{
Console.WriteLine("Lungs!");
}
}
class Dog : Mammal
{
// ERROR! Can't override sealed method
public override void Breathe() { }
}
When to Use Sealed
| Use Case | Example |
|---|---|
| Security | Don’t let anyone change critical logic |
| Performance | Compiler can optimize sealed classes |
| Design | You’re done extending this class |
graph TD A[Animal] --> B[Mammal - seals Breathe] B --> C[Dog - CANNOT override] B --> D[Cat - CANNOT override]
🎓 Quick Summary
| Concept | What It Means | Key Symbol |
|---|---|---|
| Inheritance | Child gets parent’s stuff | : |
base |
Call parent | base.Method() |
| Override | Replace parent’s method | override |
| Shadow | Hide parent’s method | new |
virtual |
“You can change this” | virtual |
abstract |
“You must change this” | abstract |
| Abstract Class | Can’t make objects | abstract class |
| Polymorphism | Same call, different behavior | 🎭 |
| Sealed | “Nobody can change this” | sealed |
🌈 The Big Picture
Think of OOP like a royal family:
- King (Base Class) - Has all the power and skills
- Princes/Princesses (Derived Classes) - Inherit the kingdom
base- Calling dad for advicevirtual/override- “Do it your way, kid”abstract- “You MUST learn this skill”sealed- “This crown stays with me!”- Polymorphism - Every royal can “Rule()” differently
And they all coded happily ever after. The End. 🏰✨