100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Inheritance in C#

Learn how C# classes derive from a single base class to reuse and extend behavior, including virtual/override methods, base member access, and sealing.

OOP BasicsIntermediate10 min readJul 9, 2026
Analogies

Inheritance in C#

Inheritance lets one class (the derived, or subclass) acquire the members of another class (the base, or superclass), expressing an 'is-a' relationship: a Manager is an Employee, a SqlLogger is a Logger. C# supports single inheritance for classes — a class can derive from exactly one base class — while allowing a type to implement any number of interfaces, which together give you controlled code reuse without the diamond-inheritance ambiguity that multiple class inheritance can create. Inheritance is one of the four pillars of object orientation alongside encapsulation, polymorphism, and abstraction, and it underlies how frameworks like ASP.NET Core and Unity structure extensible base types.

🏏

Cricket analogy: A wicketkeeper-batsman 'is-a' batsman with extra keeping duties added on, single inheritance from one batting lineage, while also implementing captaincy and slip-fielding abilities independently, avoiding the ambiguity of belonging to two conflicting batting schools at once.

Declaring a derived class

You declare inheritance with a colon after the class name: 'class Manager : Employee'. The derived class automatically gains all accessible members of the base class — public and protected members are visible, private members are not directly accessible but still exist and are managed by the base class's own methods. A derived class can add brand-new members, and it can override members the base class explicitly marked as overridable.

🏏

Cricket analogy: Declaring 'class Manager : Employee' is like a young cricketer joining the national academy under a senior mentor's program — they inherit the mentor's public coaching methods and protected drills, but not the mentor's private personal notes, while adding their own signature shots.

csharp
public class Employee
{
    public string Name { get; }
    protected decimal BaseSalary { get; }

    public Employee(string name, decimal baseSalary)
    {
        Name = name;
        BaseSalary = baseSalary;
    }

    public virtual decimal CalculatePay() => BaseSalary;
}

public class Manager : Employee
{
    public decimal Bonus { get; }

    public Manager(string name, decimal baseSalary, decimal bonus)
        : base(name, baseSalary)
    {
        Bonus = bonus;
    }

    public override decimal CalculatePay() => base.CalculatePay() + Bonus;
}

virtual, override, and new

A base method must be marked 'virtual' (or be part of an interface, or be 'abstract') before a derived class is allowed to 'override' it — this is a deliberate design choice in C#, unlike Java where every non-final method is implicitly overridable. 'override' replaces the base implementation polymorphically: calling the method through a base-typed reference still invokes the derived version at runtime. The unrelated 'new' modifier instead hides a base member with an unrelated implementation — calls resolve based on the compile-time (static) type of the reference, not the runtime type, which is almost always the wrong tool when polymorphism is what you actually want.

🏏

Cricket analogy: A batting technique marked as a customizable stance (virtual) lets a protégé genuinely replace it with their own (override), so calling it through any reference still uses the new stance; but an unrelated stance slapped on with 'new' only shows up if you specifically look at that player's own scorecard, not the general team sheet.

Accessing base members and sealing

'base.Member' from within a derived class explicitly invokes the base class's version, commonly used inside an override to extend rather than fully replace behavior (as CalculatePay does above). A class or an individual override can be marked 'sealed' to forbid further derivation or further overriding respectively — useful for locking down a class's design once you're confident no further specialization should occur, and it lets the JIT devirtualize calls for a small performance gain.

🏏

Cricket analogy: A player extending the family's classic cover drive calls back to the fundamental technique before adding their own flourish, and once a legendary stance is declared final by the academy (sealed), no further student may modify it, letting coaches teach it with total certainty.

csharp
public sealed class Executive : Manager
{
    public Executive(string name, decimal baseSalary, decimal bonus)
        : base(name, baseSalary, bonus) { }

    public override decimal CalculatePay() => base.CalculatePay() * 1.1m; // last override allowed
}
// 'class VP : Executive' would fail to compile — Executive is sealed

C# requires explicit 'virtual'/'override' keywords on both sides, making overriding intent visible at the declaration site — this avoids Java's 'fragile base class' problem where adding a same-signature method to a base class can silently change a subclass's behavior.

Using 'new' to hide a base member instead of 'override' is a frequent source of bugs: code that holds a base-typed reference will call the base implementation even though the object is actually of the derived type, because member hiding is resolved statically, not virtually.

  • C# classes support single inheritance; a class derives from exactly one base class using ':'.
  • Only members marked virtual, abstract, or defined in an interface can be overridden.
  • 'override' provides true polymorphic dispatch; 'new' merely hides a base member and resolves statically.
  • 'base.Member' calls the base class's implementation explicitly, often to extend rather than replace it.
  • 'sealed' on a class prevents further derivation; on a member it prevents further overriding.
  • Constructors are not inherited — a derived class must define its own and chain to a base constructor.

Practice what you learned

Was this page helpful?

Topics covered

#CStudyNotes#Programming#InheritanceInC#Inheritance#Declaring#Derived#Class#OOP#StudyNotes#SkillVeris