C# · Chapter 3.11 · Pro level
Inheritance & Polymorphism (Enemy → Boss)
Inheritance और Polymorphism (Enemy → Boss)
A game has many enemies — Goblin, Skeleton, Dragon Boss. They all have a name, health and an attack. Instead of copying the same code again and again, we write it once in a parent class Enemy and create child classes with class Boss : Enemy. The child inherits (gets) everything from the parent, just like a child gets the family surname. The parent marks a method virtual (children may change this) and the child writes override to give its own version. : base(name, health) sends values up to the parent's constructor. Now the magic: put all enemies in ONE List<Enemy> and call e.Attack() — every object runs ITS OWN version. One call, many forms = polymorphism. (An abstract method has no body at all, and every child MUST override it.)
गेम में बहुत सारे दुश्मन होते हैं — Goblin, Skeleton, Dragon Boss। सबके पास नाम, health और हमला होता है। एक ही कोड बार-बार कॉपी करने की जगह हम उसे एक बार parent class Enemy में लिखते हैं और class Boss : Enemy से child classes बनाते हैं। Child, parent की सारी चीज़ें विरासत में (inherit) पा लेता है — जैसे बच्चे को परिवार का सरनेम मिलता है। Parent किसी method को virtual लिखता है (बच्चे इसे बदल सकते हैं) और child override लिखकर अपना version देता है। : base(name, health) वैल्यू ऊपर parent के constructor को भेजता है। अब जादू: सारे दुश्मन एक ही List<Enemy> में रखो और e.Attack() बुलाओ — हर object अपना ख़ुद का version चलाता है। एक कॉल, कई रूप = polymorphism। (abstract method की कोई body नहीं होती, और हर child को उसे override करना ही पड़ता है।)
Words and symbols in this chapter
class Boss : Enemy- Boss is a child of Enemy and gets all its fields and methods.
- Boss, Enemy का child है और उसके सारे fields और methods पाता है।
public virtual void Attack()- The parent version;
virtualallows children to replace it. - Parent वाला version;
virtualबच्चों को इसे बदलने देता है। public override void Attack()- The child’s own version of the same method.
- उसी method का child वाला अपना version।
: base(name, health)- Calls the parent constructor first, so Name and Health are set.
- पहले parent का constructor बुलाता है, ताकि Name और Health सेट हो जाएँ।
List<Enemy> wave- One list can hold Enemy AND Boss objects (a Boss is an Enemy).
- एक list में Enemy और Boss दोनों objects रह सकते हैं (Boss भी एक Enemy है)।
abstract- A method with no body that every child must override; an abstract class cannot be created with
new. - बिना body वाला method जिसे हर child को override करना पड़ता है; abstract class से
newनहीं बनता।
Ready example
using System;
using System.Collections.Generic;
class Enemy {
public string Name;
public int Health;
public Enemy(string name, int health) {
Name = name;
Health = health;
}
public virtual void Attack() {
Console.WriteLine(Name + " hits you for 5 damage");
}
}
class Boss : Enemy {
public int Rage;
public Boss(string name, int health, int rage) : base(name, health) {
Rage = rage;
}
public override void Attack() {
Console.WriteLine(Name + " breathes FIRE for " + (10 * Rage) + " damage!");
}
}
class Program {
static void Main() {
List<Enemy> wave = new List<Enemy>();
wave.Add(new Enemy("Goblin", 30));
wave.Add(new Enemy("Skeleton", 40));
wave.Add(new Boss("Dragon King", 500, 3));
foreach (Enemy e in wave) {
e.Attack();
}
Console.WriteLine("Enemies in wave: " + wave.Count);
}
}
What you will see: Each enemy attacks in turn — the Dragon King uses its own override.
हर दुश्मन बारी-बारी हमला करता है — Dragon King अपना override वाला हमला करता है।
Line by line
class Enemy { ... public virtual void Attack() { ... } }- The shared blueprint for every enemy.
- हर दुश्मन का साझा नक्शा।
class Boss : Enemy { ... : base(name, health) ... }- Boss reuses Enemy and adds its own
Rage. - Boss, Enemy को दोबारा इस्तेमाल करता है और अपना
Rageजोड़ता है। public override void Attack() { ... }- The Boss breathes fire instead of a normal hit.
- Boss सामान्य वार की जगह आग उगलता है।
foreach (Enemy e in wave) { e.Attack(); }- The same call: Goblin hits, Dragon breathes fire (polymorphism).
- एक ही कॉल: Goblin मारता है, Dragon आग उगलता है (polymorphism)।
Common mistake
✗ Wrong
class Enemy {
public void Attack() { }
}
class Boss : Enemy {
public override void Attack() { }
}✓ Right
class Enemy {
public virtual void Attack() { }
}
class Boss : Enemy {
public override void Attack() { }
}You can only override a method that the parent marked virtual (or abstract) — otherwise you get error CS0506.
आप सिर्फ़ उसी method को override कर सकते हो जिसे parent ने virtual (या abstract) लिखा हो — वरना error CS0506 आती है।
Your task
Create class Archer : Enemy whose constructor calls base(name, 60) and which overrides Attack() to print <Name> shoots an arrow!. Then add new Archer("Robin") to the wave.
class Archer : Enemy बनाओ जिसका constructor base(name, 60) बुलाए और जो Attack() को override करके <Name> shoots an arrow! छापे। फिर wave में new Archer("Robin") जोड़ो।
- Below
class Enemy, writeclass Archer : Enemy {and close it with}.class Enemyके नीचेclass Archer : Enemy {लिखो और}से बंद करो। - Inside:
public Archer(string name) : base(name, 60) { }andpublic override void Attack() { Console.WriteLine(Name + " shoots an arrow!"); }.
अंदर:public Archer(string name) : base(name, 60) { }औरpublic override void Attack() { Console.WriteLine(Name + " shoots an arrow!"); }। - In
Mainaddwave.Add(new Archer("Robin"));and Run — you should seeRobin shoots an arrow!.Mainमेंwave.Add(new Archer("Robin"));जोड़कर Run करो —Robin shoots an arrow!दिखना चाहिए।
Starter code for the task
using System;
using System.Collections.Generic;
class Enemy {
public string Name;
public int Health;
public Enemy(string name, int health) {
Name = name;
Health = health;
}
public virtual void Attack() {
Console.WriteLine(Name + " hits you!");
}
}
// TODO 1: class Archer : Enemy banao
// TODO 2: uska constructor: public Archer(string name) : base(name, 60) { }
// TODO 3: public override void Attack() jo Name + " shoots an arrow!" print kare
class Program {
static void Main() {
List<Enemy> wave = new List<Enemy>();
wave.Add(new Enemy("Goblin", 30));
// TODO 4: wave.Add(new Archer("Robin")); jodo
foreach (Enemy e in wave) {
e.Attack();
}
}
}Do this task in the classroom: your code is checked automatically and you get hints if something is missing.
Recap
class Boss : Enemy— the child gets all fields and methods of the parent (inheritance).- The parent marks a method
virtual, the child replaces it withoverride;: base(...)calls the parent constructor. - A
List<Enemy>can hold every kind of enemy, and each runs its ownAttack()(polymorphism).
class Boss : Enemy— child को parent के सारे fields और methods मिलते हैं (inheritance)।- Parent method को
virtualलिखता है, childoverrideसे बदलता है;: base(...)parent का constructor बुलाता है। List<Enemy>में हर तरह का दुश्मन रह सकता है, और हर एक अपनाAttack()चलाता है (polymorphism)।
Quick quiz
Enemy e = new Boss("Dragon", 500, 3); e.Attack(); — Boss overrides Attack(). Which version runs?
Enemy e = new Boss("Dragon", 500, 3); e.Attack(); — Boss ने Attack() override किया है। कौन-सा version चलेगा?
Show the answer
Answer: B (Boss.Attack() — the real type of the object decides)
With virtual/override, C# runs the version of the object’s real class — that is polymorphism.
virtual/override के साथ C# object की असली class वाला version चलाता है — यही polymorphism है।
Practice problems for this chapter
- Boss Battle (inheritance + override)
बॉस बैटल (inheritance + override)
Solve them in the Practice Zone, where each answer is checked automatically and two hints are available.