C# Programming Tutorial 0/45 lessons ~6 min read Lesson 17

    Inheritance

    Inheritance models is-a relationships: SavingsAccount is an Account.

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Inheritance models is-a relationships: SavingsAccount is an Account. Derived classes inherit members and can override virtual behavior. C# allows single base class but multiple interfaces — favor composition over deep inheritance hierarchies per modern guidance.

    abstract classes provide partial implementations; sealed prevents further derivation. Interviewers ask when inheritance vs interface and problems with fragile base class.

    This lesson implements a payment hierarchy used in later polymorphism and abstraction lessons.

    The story

    A credit union offers savings and checking accounts that share common behavior — every account has a number, accepts deposits, and must define its own withdrawal rules. Savings accounts may block overdrafts entirely, while checking accounts might allow a limited overdraft facility.

    Inheritance lets the shared deposit logic live in a base Account class while each account type overrides withdrawal behavior.

    Understanding the topic

    Key concepts

    • Single inheritance: class Derived : Base.
    • protected members visible to subclasses.
    • virtual methods overridable; override replaces behavior.
    • abstract class cannot instantiate; may have abstract methods.
    • sealed class blocks inheritance; sealed override blocks further override.
    • Composition: has-a via field often preferable to is-a.
    text
    classDiagram
    class Account {
    <<abstract>>
    +decimal Balance
    +Deposit()
    }
    class SavingsAccount {
    +ApplyInterest()
    }
    class CheckingAccount {
    +OverdraftLimit
    }
    Account <|-- SavingsAccount
    Account <|-- CheckingAccount

    Step-by-step explanation

    1. Derived constructor must call base constructor.
    2. Override methods dispatch at runtime on virtual table.
    3. new keyword hides base member — avoid unless intentional.
    4. Upcasting: Derived assigned to Base reference.
    5. Pattern matching on derived types for behavior.
    6. Interface implementation satisfies contract without inheritance.

    Practical code example

    Abstract Account with Savings and Checking derivatives:

    csharp
    namespace TechLearningPro.Inheritance;
    public abstract class Account(string accountNumber)
    {
    public string AccountNumber { get; } = accountNumber;
    public decimal Balance { get; protected set; }
    public void Deposit(decimal amount)
    {
    if (amount <= 0) throw new ArgumentOutOfRangeException(nameof(amount));
    Balance += amount;
    }
    public abstract bool TryWithdraw(decimal amount);
    }
    public sealed class SavingsAccount(string accountNumber) : Account(accountNumber)
    {
    public override bool TryWithdraw(decimal amount)
    {
    if (amount <= 0 || amount > Balance) return false;
    Balance -= amount;
    return true;
    }
    }

    Line-by-line code explanation

    • public abstract class Account(string accountNumber) defines shared structure; it cannot be instantiated directly.
    • public string AccountNumber { get; } stores the identifier common to all account types.
    • public decimal Balance { get; protected set; } allows subclasses to update balance through controlled methods.
    • Deposit(decimal amount) implements shared deposit logic in the base class.
    • if (amount <= 0) throw ... validates deposits once for every account subtype.
    • Balance += amount updates the protected balance field from the base class.
    • public abstract bool TryWithdraw(decimal amount) forces each subtype to define withdrawal rules.
    • SavingsAccount : Account(accountNumber) inherits from Account and passes the account number upward.
    • override bool TryWithdraw replaces the abstract method with savings-specific logic.
    • sealed class SavingsAccount prevents further inheritance of this concrete type.

    Key takeaway: Abstract TryWithdraw forces subclasses to define rules. protected set on Balance allows subclass mutation through base API.

    Real-world use

    Where you'll use this in production

    • Plugin hierarchies with shared base behavior.
    • ASP.NET Identity user extensions.
    • UI control inheritance in WPF (legacy).
    • Template method pattern in batch processing frameworks.

    Best practices

    • Prefer shallow hierarchies — max 2-3 levels.
    • Favor interfaces and composition for flexibility.
    • Seal classes not designed for extension.
    • Document Liskov expectations for overrides.
    • Use abstract class when shared implementation exists.

    Common mistakes

    • Deep inheritance trees breaking LSP.
    • Using new instead of override — polymorphism breaks silently.
    • Inheriting for code reuse only — use composition.
    • Calling overridable methods from base constructor.

    Advanced interview questions

    Q1BeginnerSingle vs multiple inheritance in C#?
    Single class inheritance; multiple interface implementation.
    Q2Beginnerabstract class vs interface?
    Abstract can have implementation and state; interface contract only until default interface methods.
    Q3Intermediatevirtual vs override vs new?
    virtual intended override; override replaces; new hides without polymorphism.
    Q4IntermediateLiskov Substitution Principle?
    Subtypes must be substitutable for base without breaking correctness.
    Q5AdvancedWhen refuse inheritance request from junior dev?
    When has-a fits, hierarchy depth >2, or behavior varies by strategy not type — suggest interface + composition.

    Summary

    Inheritance models is-a with single base class. abstract and virtual enable extensible hierarchies. Prefer interfaces and composition for flexibility. Override correctly for runtime polymorphism. Next: polymorphism and dynamic dispatch.

    Ready to mark this lesson complete?Track your journey across the entire course.