Constructor Inheritance

Vaibhav • September 10, 2025

In object-oriented programming, constructors are special methods used to initialize objects. When inheritance enters the picture, constructors behave in a nuanced way that often surprises beginners. In this article, we’ll explore how constructors are inherited (or not), how base class constructors are invoked, and how to design constructor chains that are clear, maintainable, and safe. We’ll build on everything you’ve learned so far about classes, methods, and object initialization.

Do constructors get inherited?

Let’s start with a common misconception: constructors are not inherited in C#. That means if you define a constructor in a base class, it does not automatically become available in the derived class. Instead, the derived class must explicitly call the base constructor using the base keyword.

class Animal
{
    public Animal(string name)
    {
        Console.WriteLine($"Animal created: {name}");
    }
}

class Dog : Animal
{
    public Dog(string name) : base(name)
    {
        Console.WriteLine("Dog constructor called");
    }
}

In this example, the Dog class does not inherit the Animal constructor. Instead, it explicitly calls it using : base(name). This is how constructor inheritance works in practice: it’s not automatic, but it’s accessible.

Constructors are not inherited because they are tied to the class’s internal initialization logic. Each class defines its own construction rules, even if it builds on a base class.

Calling base constructors - the syntax and rules

When a derived class constructor runs, it must first initialize the base class. If the base class has a parameterless constructor, this happens automatically. But if the base class only defines constructors with parameters, the derived class must explicitly call one of them.

class Vehicle
{
    public Vehicle(string type)
    {
        Console.WriteLine($"Vehicle type: {type}");
    }
}

class Car : Vehicle
{
    public Car() : base("Car")
    {
        Console.WriteLine("Car constructor");
    }
}

Here, the Car constructor calls the Vehicle constructor with a hardcoded string. If you omit the : base("Car") part, the compiler will complain because there’s no parameterless constructor in Vehicle.

If the base class has no parameterless constructor, the derived class must call a base constructor explicitly. This is a compile-time requirement.

Constructor chaining - base and derived working together

Constructor chaining refers to the process where constructors in a hierarchy call each other in a sequence. This ensures that each layer of the object is properly initialized. Let’s look at a more layered example:

class Person
{
    public string Name;
    public Person(string name)
    {
        Name = name;
        Console.WriteLine($"Person: {name}");
    }
}

class Employee : Person
{
    public int Id;
    public Employee(string name, int id) : base(name)
    {
        Id = id;
        Console.WriteLine($"Employee ID: {id}");
    }
}

When you create an Employee object, the Person constructor runs first, followed by the Employee constructor. This order ensures that the base class fields are initialized before the derived class adds its own logic.

Using constructor overloading with inheritance

You can define multiple constructors in both base and derived classes. The derived class can choose which base constructor to call depending on its own parameters. This gives you flexibility in object creation.

class Shape
{
    public Shape()
    {
        Console.WriteLine("Default Shape");
    }

    public Shape(string type)
    {
        Console.WriteLine($"Shape type: {type}");
    }
}

class Circle : Shape
{
    public Circle() : base()
    {
        Console.WriteLine("Default Circle");
    }

    public Circle(string type) : base(type)
    {
        Console.WriteLine("Typed Circle");
    }
}

Depending on which constructor you use to create a Circle, the corresponding Shape constructor is called. This pattern is common in real-world APIs where objects can be initialized in multiple ways.

Constructor visibility and accessibility

Constructors can have access modifiers like public, protected, or private. These modifiers control whether a derived class can call a base constructor.

class Base
{
    protected Base()
    {
        Console.WriteLine("Protected Base");
    }
}

class Derived : Base
{
    public Derived() : base()
    {
        Console.WriteLine("Derived constructor");
    }
}

Here, the base constructor is protected, so it’s accessible to the derived class but not to external callers. This is a common pattern when you want to restrict object creation to inheritance scenarios.

Use protected constructors in base classes when you want to enforce controlled inheritance and prevent direct instantiation.

Constructor execution order - what runs first?

When you create an object of a derived class, the base class constructor runs first. This is guaranteed by the language and ensures that the base part of the object is fully initialized before the derived part adds its own logic.

class A
{
    public A()
    {
        Console.WriteLine("A constructor");
    }
}

class B : A
{
    public B()
    {
        Console.WriteLine("B constructor");
    }
}

// Output:
// A constructor
// B constructor

This order is fixed and predictable. Even if you don’t explicitly call base(), the compiler inserts it for you if the base class has a parameterless constructor.

Designing constructor chains - clarity and safety

When designing constructors in an inheritance hierarchy, aim for clarity and safety. Avoid deep chains with too many parameters. Prefer constructors that validate inputs early and delegate to base constructors with meaningful values.

class Account
{
    public string Owner;
    public Account(string owner)
    {
        if (string.IsNullOrWhiteSpace(owner))
            throw new ArgumentException("Owner name required");
        Owner = owner;
    }
}

class SavingsAccount : Account
{
    public decimal InterestRate;
    public SavingsAccount(string owner, decimal rate) : base(owner)
    {
        if (rate < 0)
            throw new ArgumentException("Interest rate must be positive");
        InterestRate = rate;
    }
}

This pattern ensures that both base and derived constructors validate their own responsibilities. It also keeps the logic shallow and readable.

If a base class defines multiple constructors, the derived class can choose which one to call - but only one per constructor. You can’t call multiple base constructors from a single derived constructor.

Summary

Constructor inheritance in C# is not automatic - derived classes must explicitly call base constructors. This gives you control over how objects are initialized across a class hierarchy. You’ve learned how to use the base keyword, how constructor chaining works, how access modifiers affect constructor visibility, and how to design safe, readable constructor chains. These patterns are essential for building robust object-oriented systems.

In the next article, we’ll explore Abstract Classes - a powerful tool for defining shared behavior while enforcing implementation rules in derived classes.