Inheritance and Constructors

When a base class has a constructor with parameters, every derived class must call it with base(...). The base class's constructor always runs first.

Journeyman · C# · OOP · Updated

After this lesson you can

  • Call a base class's constructor from a derived class's constructor with base(...)
  • Explain the order constructors run in when an object of a derived class is created

Key takeaways

  • When the base class's constructor takes parameters, a derived class's constructor calls it with : base(...) after its parameter list.
  • The base class's constructor always runs first, then the derived class's, so the base part is set up before the derived body runs.
  • base(...) can pass any values, not only parameters: Wizard passes base(name, 80).
  • If the base class has no constructor without parameters, a derived constructor that leaves out base(...) doesn't compile (error CS7036).

A derived object is a base object too: an archer is a character. So when you create an Archer, the Character part has to be set up as well, and that's the job of Character's constructor.

base(...) calls the base class's constructor

Give Character a constructor that takes a name and health. Now there's no way to make a character without them, and that includes an archer. Archer's constructor passes them on with : base(...), written after its parameter list:

Archer robin = new Archer("Robin", 100, 12);
Console.WriteLine(quot;{robin.Name}: health {robin.Health}, arrows {robin.Arrows}");

public class Character
{
    public string Name { get; }
    public int Health { get; protected set; }
    public int Level { get; protected set; } = 1;

    public Character(string name, int health)
    {
        Console.WriteLine("Character's constructor runs");
        Name = name;
        Health = health;
    }
}

public class Archer : Character
{
    public int Arrows { get; private set; }

    public Archer(string name, int health, int arrows) : base(name, health)
    {
        Console.WriteLine("Archer's constructor runs");
        Arrows = arrows;
    }
}
Character's constructor runs
Archer's constructor runs
Robin: health 100, arrows 12

Archer takes three values. It hands name and health to Character's constructor, which sets up the character part, and keeps arrows for itself.

The base class goes first

The output shows the order: the base class's constructor runs first, then the derived class's. That's what makes it safe for Archer's constructor to use Name and Health: by the time its body runs, the character part is already set up.

base(...) can pass any values

The values passed to base(...) don't have to be parameters. Every wizard in the game starts with 80 health, so Wizard asks only for a name:

Wizard merlin = new Wizard("Merlin");
Console.WriteLine(quot;{merlin.Name}: health {merlin.Health}, mana {merlin.Mana}");

public class Character
{
    public string Name { get; }
    public int Health { get; protected set; }

    public Character(string name, int health)
    {
        Name = name;
        Health = health;
    }
}

public class Wizard : Character
{
    public int Mana { get; private set; } = 50;

    public Wizard(string name) : base(name, 80)
    {
    }
}
Merlin: health 80, mana 50

Forgetting base(...)

If the base class has no constructor without parameters, a derived class that leaves out base(...) doesn't compile:

Knight lancelot = new Knight("Lancelot", 120, 5);

public class Character
{
    public string Name { get; }
    public int Health { get; protected set; }

    public Character(string name, int health)
    {
        Name = name;
        Health = health;
    }
}

public class Knight : Character
{
    public int Armor { get; }

    public Knight(string name, int health, int armor)
    {
        Armor = armor;
    }
}
error CS7036: There is no argument given that corresponds to the required parameter 'name' of 'Character.Character(string, int)'

Without base(...), C# tries to call Character() with no arguments, and there isn't one. Add : base(name, health) after Knight's parameter list.

(When the base class has no constructor of its own, as in Inheritance in C#, C# gives it an empty one, and derived classes don't need base(...).)

Check yourself

2 questions to try on the lesson page.

So what

: base(...) hands the base class what it needs, and the base class's constructor always runs first. Every derived object is built from the bottom up: first the general part, then the special one.

Key terms

Cheat sheets