Inheritance in C#
A derived class names its base class after a colon. It inherits every member of the base class, but its code can use only the public and protected ones, never the private ones; and every class inherits from object in the end.
Apprentice · C# · OOP · Updated
After this lesson you can
- Write a derived class that inherits from a base class with a colon
- Explain which members a derived class can use, with public, protected and private
Key takeaways
public class Archer : CharactermakesArcherinherit every member ofCharacter. Read the colon as "is a".- A derived class's code can use the base class's
publicandprotectedmembers, never itsprivateones. - Give a property a
protected set, asHealthhas, when derived classes need to change it. - A C# class has only one base class, and every class inherits from
objectin the end, which gives itToString()andEquals().
In C#, a class inherits from another by naming it after a colon:
public class Archer : Character
Read it as "Archer is a Character." The base class itself is written as normal.
The base class
Archer robin = new Archer();
robin.Name = "Robin";
robin.LevelUp();
robin.AddArrow();
Console.WriteLine( quot;{robin.Name}: level {robin.Level}, health {robin.Health}, arrows {robin.Arrows}");
public class Character
{
public string Name { get; set; } = "";
public int Health { get; protected set; } = 100;
public int Level { get; protected set; } = 1;
public bool IsDefeated => Health <= 0;
public void TakeDamage(int damage)
{
Health = Math.Max(Health - damage, 0);
}
public void LevelUp()
{
if (IsDefeated)
{
return;
}
Level++;
Health += 10;
}
}
public class Archer : Character
{
public int Arrows { get; private set; }
public void AddArrow()
{
Arrows++;
}
}
Robin: level 2, health 110, arrows 1
Archer wrote only Arrows and AddArrow(). Name, Health, Level, IsDefeated, TakeDamage() and LevelUp() all came from Character. A Wizard : Character and a Knight : Character would get them too, from the same one place.
What a derived class can use
A derived class inherits every member, but the access modifiers decide which ones its code can use:
| Modifier | Who can use it |
|---|---|
public |
Any code |
protected |
The class itself, and classes derived from it |
private |
Only the class itself, not even its derived classes |
That's why Health has a protected set: anyone can read a character's health, but only Character and its derived classes can change it. A private set would stop a derived class such as Knight from changing its own health, even though it has one:
Knight lancelot = new Knight();
lancelot.Rest();
public class Character
{
public int Health { get; private set; } = 100;
}
public class Knight : Character
{
public void Rest()
{
Health += 20;
}
}
error CS0272: The property or indexer 'Character.Health' cannot be used in this context because the set accessor is inaccessible
Use private for what's truly the base class's own business, and protected for what derived classes need to change.
One base class, and object at the top
- A C# class can have only one base class.
class Archer : Character, Heroisn't allowed. - A class can be the base class of another derived class: a
Ranger : Archeris an archer, and so also a character. - Every class inherits from
objectin the end, even one with no colon. That's where every object'sToString()andEquals()come from.
Check yourself
2 questions to try on the lesson page.
So what
One colon makes Archer a Character, with everything a character has, written once. Choose protected for what derived classes may change, and the base class stays in charge of its own data.