Skip to content

Intermediate · Inheritance, interfaces and records · topic 18 of 43 · 30 min

Inheritance: base and derived classes

Explanation

Inheritance lets a new class (the derived class) start with everything an existing class (the base class) has, and add or change behaviour. You write class Savings : Account. A base method marked virtual can be replaced in the derived class with override, and base.Method() still calls the original. A class can inherit from only one class, and sealed stops further inheritance.

Why inheritance?

A bank has savings accounts and current accounts. Both have an account number, an owner and a balance, and both accept deposits. Copying that code into two classes means fixing every bug twice. Inheritance lets both classes share one base class, Account, and add only what is different.

Think of it like this: Inheritance is like a family recipe. Grandmother's dal recipe is the base. Your mother uses it but adds extra garlic (override). You inherit your mother's version and add a tadka on top. Each version keeps everything from before and changes only one step.

The "is-a" test

Use inheritance only when the derived class truly IS a kind of the base class. A SavingsAccount is an Account: good. A Car is not an Engine, it HAS an engine, so give Car an Engine property instead. That second style is called composition, and it is often the better choice.

Writing a base and a derived class

csharp
public class Account
{
    public string Owner { get; }
    public decimal Balance { get; protected set; }   // derived classes may set it

    public Account(string owner, decimal opening)
    {
        Owner = owner;
        Balance = opening;
    }

    public void Deposit(decimal amount) => Balance += amount;

    public virtual string Describe() => $"{Owner}: {Balance:F2}";
}

public class SavingsAccount : Account
{
    public decimal InterestRate { get; }

    public SavingsAccount(string owner, decimal opening, decimal rate)
        : base(owner, opening)          // run the base constructor first
    {
        InterestRate = rate;
    }

    public void AddYearlyInterest() => Balance += Balance * InterestRate;

    public override string Describe() => base.Describe() + $" (savings @ {InterestRate:P0})";
}
: Account means "inherits from Account". : base(...) passes values to the base constructor. protected set lets derived classes change Balance while outside code cannot.
csharp
var s = new SavingsAccount("Asha", 10000m, 0.04m);
s.Deposit(2000m);          // inherited from Account
s.AddYearlyInterest();     // only SavingsAccount has this
Console.WriteLine(s.Describe());
Shows Asha: 12480.00 (savings @ 4%). The P0 format shows a percentage with no decimals; the exact symbol spacing follows your culture settings.

virtual, override and base

  • virtual on a base method says "derived classes may replace this".
  • override in the derived class gives the new version. The signature must match.
  • base.Describe() inside the override calls the base version, so you can extend instead of rewriting.
  • Methods are NOT virtual unless you say so. This is different from Java, where methods are virtual by default.

Constructors and inheritance

Constructors are not inherited. When you create a SavingsAccount, the base constructor runs first, then the derived one. If the base class has no constructor without parameters, the derived constructor must call one with : base(...), or the code does not compile.

sealed: stop here

csharp
public sealed class FixedDeposit : Account
{
    public FixedDeposit(string owner, decimal amount) : base(owner, amount) { }
}
// public class SpecialFd : FixedDeposit { }   // error: cannot derive from sealed type
sealed prevents further inheritance. string is a sealed class. A sealed override stops a method from being overridden further.

Hiding with new: usually a mistake

csharp
Basic b = new Premium();
Console.WriteLine(b.Name());   // Basic!

class Basic { public string Name() => "Basic"; }
class Premium : Basic { public new string Name() => "Premium"; }
Without virtual/override, the method is chosen by the variable's type, not the object's type. new only hides the base method. Use virtual and override when you want the object's own version.

Everything inherits from object

Every C# type ultimately inherits from System.Object (object). That is why every object has ToString(), Equals() and GetHashCode(), and why you write override string ToString().

Common mistakes and fixes

  • Forgetting override: the compiler warns CS0114 that the method hides the inherited one. Add override (and make sure the base method is virtual).
  • Base class without a parameterless constructor and no : base(...) call: error CS7036. Call the right base constructor.
  • Deep hierarchies (A : B : C : D : E): hard to understand and change. Keep it to one or two levels and prefer composition.
  • Trying to inherit from two classes: C# allows one base class. Use interfaces (next topics) for extra abilities.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Inheritance: base and derived classes · 1/7

Inheritance

In this lesson a class will inherit everything from another class.

Prefer a video by a teacher? Find free videos on “C# inheritance virtual override base sealed tutorial” on YouTube ↗

In real life: Employees and managers in an HR system

An HR payroll system in Chennai pays every employee a monthly salary. Managers are employees too, but they also get a team bonus. Manager inherits from Employee and overrides only the pay calculation.

csharp
Employee[] staff =
{
    new Employee("Asha", 45000m),
    new Manager("Ravi", 80000m, teamSize: 6)
};
foreach (var e in staff)
    Console.WriteLine($"{e.Name}: {e.MonthlyPay()}");

public class Employee
{
    public string Name { get; }
    public decimal Salary { get; }
    public Employee(string name, decimal salary) { Name = name; Salary = salary; }
    public virtual decimal MonthlyPay() => Salary;
}

public class Manager : Employee
{
    public int TeamSize { get; }
    public Manager(string name, decimal salary, int teamSize) : base(name, salary) => TeamSize = teamSize;
    public override decimal MonthlyPay() => base.MonthlyPay() + TeamSize * 1500m;
}
Shows Asha: 45000 and Ravi: 89000. The loop calls MonthlyPay on each object and the right version runs.

Practice (0/4 done)

Task 1 · Question

How do you write that Dog inherits from Animal?

Task 2 · Question

What does this print? Animal a = new Dog(); Console.WriteLine(a.Sound()); class Animal { public virtual string Sound() => "..."; } class Dog : Animal { public override string Sound() => "Woof"; }

Task 3 · Question

Which keyword prevents a class from being inherited?

Task 4 · Practice

Create a base class Vehicle (Number, virtual decimal Toll()) returning 100, and two derived classes: Car (toll 100, the base value) and Truck with an Axles property whose toll is base.Toll() * Axles. Put both in a Vehicle[] and print each number and toll, as a highway toll plaza would.

Quick quiz

Question 1

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

Question 2

2.Which runs first when you create a derived object?

Question 3

3.What does base.Describe() do inside an override?

Question 4

4.Are C# methods virtual by default?

Question 5

5.A protected member can be used by...

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

How many base classes can a C# class have?

Answer: One

C# has single class inheritance; use interfaces for more abilities.

Which runs first when you create a derived object?

Answer: The base constructor

The base part is built first, then the derived part.

What does base.Describe() do inside an override?

Answer: Calls the base class version of Describe

base lets you reuse the original implementation.

Are C# methods virtual by default?

Answer: No, you must mark them virtual

Unlike Java, C# methods are non-virtual unless marked virtual.

A protected member can be used by...

Answer: The same class and derived classes

protected opens access to derived classes.

Which base members can a derived class use directly?Related

Answer: public and protected

private members stay hidden even from derived classes.

From Inheritance: building on an existing class

A base constructor calls a virtual function. Which version runs?Related

Answer: The base version, because the derived part is not built yet

During base construction the object behaves as a base object.

From Virtual functions and polymorphism

Can an abstract class have a constructor and data members?Related

Answer: Yes; it just cannot be instantiated on its own

Abstract only means "cannot be created directly". It may still hold shared data and constructors for derived classes.

From Abstract classes, interfaces and good class design

Which class does every Java class ultimately extend?Related

Answer: Object

java.lang.Object is the root of all classes.

From Inheritance with extends

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Inheritance, interfaces and records” before its exam: Abstract classes and polymorphism, Interfaces: contracts for behaviour, Records and pattern matching.
  2. Module 5 exam: Inheritance, interfaces and records · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Collections, generics and LINQ. 43 topics left in the course before the final exam.

← Previous: Structs, value types and reference types