Inheritance ๐งฌ
Learn How Classes Can Be Family! (It's Easier Than You Think!)
Hey there, Future C# Master! ๐
Welcome to Inheritance - one of the coolest features in C#! Don't worry, I won't use big fancy words. We'll learn together, step by step.
- โ Explain inheritance like a pro (but in simple words)
- โ Create parent and child classes
- โ Use the 'base' keyword (it's not scary, I promise!)
- โ Override methods (change how things work)
- โ Build your own inheritance hierarchies
Part 1: What is Inheritance? (The Easy Way)
๐จโ๐ฉโ๐งโ๐ฆ The Family Analogy
Imagine a Parent class called Animal:
- ๐พ Every animal has a Name
- ๐พ Every animal has an Age
- ๐พ Every animal can Eat()
- ๐พ Every animal can Sleep()
Now, a Child class called Dog inherits from Animal:
- ๐ Dog gets Name, Age, Eat(), Sleep()
- ๐ Dog adds its own things: Breed, Bark()
๐ป Code Time!
Parent Class (Animal):
public class Animal
{
public string Name;
public int Age;
public void Eat()
{
Console.WriteLine($"{Name} is eating!");
}
}
Child Class (Dog):
public class Dog : Animal // ๐ This means "inherits"
{
public string Breed;
public void Bark()
{
Console.WriteLine($"{Name} says Woof!");
}
}
Dog automatically has Name, Age, and Eat()!
Part 2: The ':' Symbol - The Magic Link
๐ The Connection
The ':' symbol is like a bridge between parent and child.
public class Child : Parent // ๐ The ':' means "inherits from"
{
// Child gets everything from Parent
}
or "Child is a Parent"
๐ Real Examples
// Dog IS AN Animal
public class Dog : Animal { }
// Car IS A Vehicle
public class Car : Vehicle { }
// Student IS A Person
public class Student : Person { }
โ "A Dog IS AN Animal"
โ "A Dog IS A Car" (That would be weird!)
Part 3: The 'base' Keyword - Calling Mom and Dad
Calling Parent Constructor
When you create a child, the parent must be built first:
public class Animal
{
public string Name;
public Animal(string name)
{
Name = name;
Console.WriteLine("๐พ Animal created!");
}
}
public class Dog : Animal
{
public string Breed;
public Dog(string name, string breed)
: base(name) // ๐ Calls parent first!
{
Breed = breed;
Console.WriteLine("๐ Dog created!");
}
}
Output: "๐พ Animal created!" then "๐ Dog created!"
Calling Parent Methods
You can also call parent methods:
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
base.MakeSound(); // ๐ First, do parent's thing
Console.WriteLine("Dog barks: Woof!"); // Then add extra
}
}
๐ base.MakeSound() runs the parent's version first!
Part 4: Virtual and Override - Changing the Rules
Sometimes, children want to change how they do things. That's where virtual and override come in!
virtual
Parent says: "You can change this if you want"
public virtual void Speak()
{
Console.WriteLine("I speak...");
}
override
Child says: "I'm changing this!"
public override void Speak()
{
Console.WriteLine("I bark!");
}
Why Do This?
- โ Make animals sound different
- โ Make each car start differently
- โ Customize behavior without changing parent
Dog d = new Dog();
d.Speak(); // "I bark!"
๐ Real Example
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Sound!");
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Meow!");
}
}
public class Cow : Animal
{
public override void MakeSound()
{
Console.WriteLine("Moo!");
}
}
๐ Each animal makes its own sound!
Part 5: Protected - The Family Secret
๐ก๏ธ What is Protected?
Protected means "Only me and my children can see this."
public class Person
{
protected string SSN; // Family secret
public string Name; // Everyone knows
}
โ Child Can See It
public class Employee : Person
{
public void ShowSSN()
{
Console.WriteLine(SSN); // โ
Allowed! (Child can see)
}
}
๐ Children can access protected members
public
๐ Everyone
Like your nameprotected
๐จโ๐ฉโ๐งโ๐ฆ Family Only
Like a family recipeprivate
๐ Just You
Like your passwordPart 6: Building a Family Tree (Hierarchy)
You can create a chain of inheritance - like a family tree!
๐ณ The Animal Kingdom
Animal (Base)
Mammal + Fur, Tail
Bird + Wings, Fly
Fish + Fins, Swim
Dog + Breed
Cat + Meow
Eagle + Hunt
Salmon + Swim
Each level adds more specific features!
๐ป Code for This
public class Animal { public string Name; }
public class Mammal : Animal { public string Fur; }
public class Dog : Mammal { public string Breed; }
โ What Dog Inherits
- โ From Animal: Name
- โ From Mammal: Fur
- โ Its own: Breed
Dog d = new Dog();
d.Name = "Rex"; // From Animal
d.Fur = "Brown"; // From Mammal
d.Breed = "Lab"; // Dog's own
Part 7: Sealed - The "No More Children" Rule
Sealed is like saying "I'm the last one - no more children after me!"
๐ Sealed Class
public sealed class FinalClass
{
public string Data;
}
// โ This will NOT work:
// public class Child : FinalClass { } // ERROR!
โ Cannot inherit from a sealed class
โ When to Use Sealed
- โ Security - Don't want anyone changing your code
- โ Performance - Slightly faster
- โ Design - Class is perfect as-is
string class is sealed - you can't inherit from it!
Part 8: Real-World Example - A Pizza Shop! ๐
Let's build a Pizza inheritance system - because who doesn't love pizza?
// Base Pizza - The Original ๐
public class Pizza
{
public string Name = "Plain Pizza";
public decimal Price = 10.00m;
public virtual void Describe()
{
Console.WriteLine($"๐ {Name} - ${Price}");
}
}
// Pepperoni Pizza - A Child ๐+๐ฅ
public class PepperoniPizza : Pizza
{
public PepperoniPizza()
{
Name = "Pepperoni Pizza";
Price = 12.00m;
}
public override void Describe()
{
Console.WriteLine($"๐ {Name} - ${Price} with lots of pepperoni!");
}
}
// Supreme Pizza - A Child of Pizza ๐+๐ฅ+๐ถ๏ธ+๐ง
public class SupremePizza : Pizza
{
public SupremePizza()
{
Name = "Supreme Pizza";
Price = 14.00m;
}
public override void Describe()
{
Console.WriteLine($"๐ {Name} - ${Price} with EVERYTHING!");
}
}
// Gourmet Pizza - Sealed (No more changes!)
public sealed class GourmetPizza : Pizza
{
public GourmetPizza()
{
Name = "Gourmet Pizza";
Price = 20.00m;
}
public override void Describe()
{
Console.WriteLine($"๐ {Name} - ${Price} with truffle oil!");
}
}
// Program.cs - Ordering Pizzas
class Program
{
static void Main()
{
Console.WriteLine("๐ Welcome to C# Pizza Shop!\n");
Pizza plain = new Pizza();
PepperoniPizza pepperoni = new PepperoniPizza();
SupremePizza supreme = new SupremePizza();
GourmetPizza gourmet = new GourmetPizza();
plain.Describe(); // Plain Pizza - $10.00
pepperoni.Describe(); // Pepperoni Pizza - $12.00 with pepperoni!
supreme.Describe(); // Supreme Pizza - $14.00 with EVERYTHING!
gourmet.Describe(); // Gourmet Pizza - $20.00 with truffle oil!
}
}
- โ Inheritance - All pizzas inherit from Pizza
- โ Virtual/Override - Each pizza describes itself differently
- โ Sealed - GourmetPizza can't be extended
- โ Polymorphism - We treat all pizzas as Pizza!
Part 9: Let's Practice! ๐ฎ
You'll create different character types (Warrior, Mage, Archer) that all share common traits but have their own special abilities.
๐ฎ About This Application
This is a Role-Playing Game (RPG) Character System. In video games like:
- ๐ฏ World of Warcraft - Warriors, Mages, Hunters
- โ๏ธ Diablo - Barbarian, Wizard, Demon Hunter
- ๐น Elder Scrolls - Warrior, Mage, Archer
Each character type shares common things (name, health, attack) but does things differently. This is perfect for inheritance because:
- โ All characters are Characters (is-a relationship)
- โ Each type adds its own special features
- โ Each type changes (overrides) how they attack
Your Mission:
-
Base Class: Character
- Properties: Name, Health
- Method: Attack() - virtual
-
Derived: Warrior
- Property: Weapon
- Override: Attack() - "swings sword"
-
Derived: Mage
- Property: Spell
- Override: Attack() - "casts spell"
-
Derived: Archer
- Property: Bow
- Override: Attack() - "shoots arrow"
๐ก How This Organizes Your Code
- โ Common code (Name, Health) goes in Character - write once!
- โ Special code (Weapon, Spell, Bow) goes in each child class
- โ Different behavior (Attack) uses override - each type attacks differently
- โ Easy to add new character types later (just create another child)
// ===== RPG CHARACTER SYSTEM =====
// This is a complete character system for a video game
// It shows how inheritance helps organize game code
// Base Character - The common traits all characters share
public class Character
{
public string Name { get; set; }
public int Health { get; set; }
public Character(string name, int health)
{
Name = name;
Health = health;
}
public virtual void Attack()
{
Console.WriteLine($"{Name} attacks!");
}
}
// Warrior - A powerful melee fighter
public class Warrior : Character
{
public string Weapon { get; set; }
public Warrior(string name, int health, string weapon)
: base(name, health)
{
Weapon = weapon;
}
public override void Attack()
{
Console.WriteLine($"โ๏ธ {Name} swings {Weapon}!");
}
}
// Mage - A powerful spell caster
public class Mage : Character
{
public string Spell { get; set; }
public Mage(string name, int health, string spell)
: base(name, health)
{
Spell = spell;
}
public override void Attack()
{
Console.WriteLine($"๐ฎ {Name} casts {Spell}!");
}
}
// Archer - A ranged combat specialist
public class Archer : Character
{
public string Bow { get; set; }
public Archer(string name, int health, string bow)
: base(name, health)
{
Bow = bow;
}
public override void Attack()
{
Console.WriteLine($"๐น {Name} shoots {Bow}!");
}
}
// Program.cs - Testing the RPG System
class Program
{
static void Main()
{
Console.WriteLine("โ๏ธ RPG CHARACTER SYSTEM โ๏ธ");
Console.WriteLine("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n");
// Create different character types
Warrior warrior = new Warrior("Conan", 100, "Sword");
Mage mage = new Mage("Merlin", 80, "Fireball");
Archer archer = new Archer("Legolas", 90, "Longbow");
// Each attacks differently (override)
warrior.Attack(); // โ๏ธ Conan swings Sword!
mage.Attack(); // ๐ฎ Merlin casts Fireball!
archer.Attack(); // ๐น Legolas shoots Longbow!
// Polymorphism - treating all as Character
Console.WriteLine("\n๐ Polymorphism: Treating all as Character");
Character[] characters = { warrior, mage, archer };
foreach (var character in characters)
{
character.Attack(); // Each uses its own override!
}
}
}