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 : Character makes Archer inherit every member of Character. Read the colon as "is a".
  • A derived class's code can use the base class's public and protected members, never its private ones.
  • Give a property a protected set, as Health has, when derived classes need to change it.
  • A C# class has only one base class, and every class inherits from object in the end, which gives it ToString() and Equals().

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, Hero isn't allowed.
  • A class can be the base class of another derived class: a Ranger : Archer is an archer, and so also a character.
  • Every class inherits from object in the end, even one with no colon. That's where every object's ToString() and Equals() 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.

Key terms

Cheat sheets