Introduction (override)
Generic Parent Trap
Imagine you are Building a game. you have base class called Enemy. You want every enemy to have a PerformAction() method.
Virtual Methods are the secret to making object smart enough to change their behavior while the game is running. but for this to work, you must have a “Family Tree” (inheritance).
The Issue : The “Static” Wall (NO Virtual)
Imagine you have a base Enemy class and a Mage class. You use Inheritance, but you don’t use virtual or override.
// PARENT
public class Enemy
{
public void Attack()
{
Console.WriteLine("Enemy deals 10 damage.");
}
}
// CHILD
public class Mage : Enemy
{
// The child tries to make its own version
public void Attack()
{
Console.WriteLine("Mage casts a Fireball for 50 damage!");
}
}
The Hidden problem
When you hold a Mage inside an Enemy variable (which happens all the time in game engines), the computer gets “confused.”
Enemy myMonster = new Mage();
myMonster.Attack(); // Enemy deals 10 damage.
Mage myMonster1 = new Mage();
myMonster.Attack(); // Mage casts a Fireball for 50 damage!
The Result: It prints Enemy deals 10 damage. Why? Because the computer looks at the Variable Label (Enemy) instead of the Actual Object (Mage). It doesn’t see the Mage’s attack because there was no “link” created between them.
The “Array” Problem
If you don’t use virtual, the computer only looks at the “Array Label” (Enemy[]). It doesn’t care what is actually inside the slots.
// We create an array that can hold 3 enemies
Enemy[] dungeon = new Enemy[3];
dungeon[0] = new Mage(); // A Mage in the first slot
dungeon[1] = new Archer(); // An Archer in the second slot
dungeon[2] = new Enemy(); // A basic Enemy in the third slot
foreach (Enemy e in dungeon)
{
// WITHOUT VIRTUAL:
// The computer sees the array is "Enemy[]",
// so it only runs the Parent logic for everyone.
e.Attack();
}
The Solution
virtual and override create a Dynamic Link (a phone line) between the Parent and the Child.
The Virtual (Parent’s Permission)
When a Parent class creates a method, it is usually “locked.” If the Parent wants to give the Child permission to change that method, it must use the keyword virtual.
virtualmeans “Here is my version of the logic, but I give my children permission to change it if they want to.”
The Override ( Childs Actions)
When the Child decides to actually change that logic, it must use the keyword override.
overridemeans “I am taking the permission my parent gave me and replacing their logic with my own.”
The Fixed code
// PARENT: We add 'virtual' to grant permission
public class Enemy
{
public virtual void Attack()
{
Console.WriteLine("Enemy deals 10 damage.");
}
}
// CHILD: We add 'override' to claim that permission
public class Mage : Enemy
{
public override void Attack()
{
Console.WriteLine("Mage casts a Fireball for 50 damage!");
}
}
// CHILD 2: The Archer
public class Archer : Enemy
{
public override void Attack()
{
Console.WriteLine("Archer fires a Piercing Arrow for 30 DMG!");
}
}
// CHILD 3: The Boss
public class DragonBoss : Enemy
{
public override void Attack()
{
Console.WriteLine("DRAGON BREATHS FIRE! 500 DMG! GAME OVER!");
}
}
// 1. We create a generic "Label"
Enemy currentTarget;
currentTarget = new Enemy();
currentTarget.Attack(); // Output: "Enemy deals 10 damage."
currentTarget = new Mage();
currentTarget.Attack(); // Output: " Mage casts a Fireball!"
currentTarget = new DragonBoss();
currentTarget.Attack(); // Output: " DRAGON BREATHS FIRE!"
// We have an array of the Parent type
Enemy[] battlefield = new Enemy[3];
battlefield[0] = new Mage();
battlefield[1] = new Archer();
battlefield[2] = new DragonBoss();
Console.WriteLine("--- THE BATTLE BEGINS ---");
foreach (Enemy e in battlefield)
{
// ONE line of code produces FOUR different results!
e.Attack();
}
Dynamic Polymorphism is the ability of a single variable to trigger different behaviors at Runtime. It allows a Parent variable to “see” and “execute” the specialized logic of its Child.
The Three Requirements
For the solution to work, you must have these three “Pillars” in place:
-
Inheritance (
:): There must be a Parent-Child relationship. -
virtual(The Permission): The Parent must explicitly allow its method to be replaced. -
override(The Claim): The Child must explicitly state it is providing a new version.
The Internal Logic
When the computer hits the line e.Attack(), it follows this internal logic:
-
Check the Label: The variable is an
Enemy. DoesEnemyhave anAttack()method? (Yes) -
Check the Permission: Is that method marked
virtual? (Yes) -
Check the Reality: Stop! Don’t run the Parent code yet. Look at the Actual Object in memory. If it’s a
Mage, and that Mage has anoverride, run the Mage’s code instead.