.NET Academy

Inheritance

Build specialized classes on top of general ones and reuse their code.

10 min read

You will learn

  • Derive a class from a base class
  • Call a base constructor with base(...)
  • Use protected members
  • Recognize when inheritance is (and isn't) the right tool

Specialized versions of a general idea

A company has employees. Some employees are managers: they have everything an employee has (name, salary) plus a team. Rather than copy the employee code into a Manager class, C# lets Manager inherit from Employee.

class Employee
{
    public string Name { get; }
    public decimal Salary { get; protected set; }
 
    public Employee(string name, decimal salary)
    {
        Name = name;
        Salary = salary;
    }
 
    public string Introduce() => $"Hi, I'm {Name}";
}
 
class Manager : Employee
{
    public List<Employee> Team { get; } = new();
 
    public Manager(string name, decimal salary) : base(name, salary)
    {
    }
 
    public void Hire(Employee e) => Team.Add(e);
}
  • Employee is the base class (or parent); Manager is the derived class (or child).
  • Manager automatically has Name, Salary and Introduce() — it inherits them.
  • It adds its own members: Team and Hire.
var boss = new Manager("Grace", 9000);
boss.Hire(new Employee("Linus", 5000));
 
Console.WriteLine(boss.Introduce());     // Hi, I'm Grace — inherited method
Console.WriteLine(boss.Team.Count);      // 1

Calling the base constructor

A derived class must make sure the base part of the object is initialized. : base(...) passes arguments to the base class constructor, which runs first:

public Manager(string name, decimal salary) : base(name, salary)
{
    // by now, Name and Salary are already set
}

If the base class has a parameterless constructor, it's called automatically; otherwise : base(...) is required.

is-a: a derived object is a base object

Because every Manager is an Employee, you can use a manager wherever an employee is expected:

Employee e = new Manager("Grace", 9000);   // ✅ allowed
List<Employee> staff = [new Employee("Linus", 5000), new Manager("Grace", 9000)];
 
Console.WriteLine(e is Manager);           // True — check the actual type at run time

The reverse isn't true: not every Employee is a Manager.

protected: for the family only

ModifierAccessible from
privateThis class only
protectedThis class and classes derived from it
publicEverywhere

In Employee, Salary has a protected set: managers' code (say, a GiveRaise method on a subclass) can change salaries, but outside code can't.

Every class inherits from object

If you don't specify a base class, it's object (System.Object). That's why every type has methods like ToString(), Equals() and GetType():

var e = new Employee("Linus", 5000);
Console.WriteLine(e.GetType().Name);    // Employee
Console.WriteLine(e.ToString());        // "Employee" — the default; you'll override it next lesson

sealed: no further inheritance

Mark a class sealed to prevent anyone deriving from it: sealed class Settings { ... }. string is sealed, for example.

Inheritance vs composition

Inheritance is powerful but creates tight coupling: changes to a base class ripple into every derived class. Use it for real is-a relationships. For has-a relationships, use composition — give the class a field holding another object:

class Car
{
    private readonly Engine engine = new();   // a Car HAS an Engine — it isn't one
    public void Start() => engine.Ignite();
}

Favor composition

A common design guideline: favor composition over inheritance. Reach for inheritance when you need polymorphism (next lesson), not just to reuse a few methods.

Try it

Program.cs
Loading editor…

C# runtime not loaded

Key takeaways

  • class Derived : Base inherits all of Base's members and adds its own.
  • Derived constructors pass arguments to the base with : base(...).
  • A derived object can be used wherever the base type is expected (is-a).
  • protected members are visible to derived classes; every class ultimately derives from object.
  • Prefer composition for has-a relationships.

Exercise

Animal is complete. Make Dog inherit from Animal: its constructor takes a name and a breed, passes the name to Animal's constructor, and stores the breed in a Breed property. Add a Bark method that returns "<name> says Woof!".

Program.cs
Loading editor…

C# runtime not loaded

Hint 1

Inheritance syntax: class Dog : Animal { ... }

Hint 2

Animal has no parameterless constructor, so Dog's constructor must call it: public Dog(string name, string breed) : base(name) { ... }

Show solution
var animal = new Animal("Generic");
Console.WriteLine(animal.Describe());

class Animal
{
    public string Name { get; }

    public Animal(string name)
    {
        Name = name;
    }

    public string Describe() => $"{Name} is an animal";
}

class Dog : Animal
{
    public string Breed { get; }

    public Dog(string name, string breed) : base(name)
    {
        Breed = breed;
    }

    public string Bark() => $"{Name} says Woof!";
}

Quiz

4 questions · 3 correct to pass
  1. 1.What does `class Cat : Animal` mean?

  2. 2.How many base classes can a C# class have?

  3. 3.Who can access a protected member?

  4. 4.When is inheritance a good fit?

To complete this lesson

  • ○ Solve the exercise
  • ○ Pass the quiz (3/4 correct)