Lesson 15 — Class Hierarchies

Inheritance

C# inheritance uses : instead of extends; base instead of super; methods must be declared virtual before they can be overridden — a stricter but safer model than Java.

CSHARP — Inheritance
public class Person {
    protected string Name { get; }
    protected int    Age  { get; }

    public Person(string name, int age) {
        Name = name;
        Age  = age;
    }

    // virtual — subclasses CAN override this
    public virtual void Introduce() =>
        Console.WriteLine($"Hello, I am {Name}, aged {Age}.");
}

public class Learner : Person  // : instead of Java's extends
{
    public string Course { get; }
    public double Mark   { get; set; }

    public Learner(string name, int age, string course, double mark)
        : base(name, age)  // base() instead of Java's super()
    {
        Course = course;
        Mark   = mark;
    }

    public override void Introduce() =>  // override keyword required
        Console.WriteLine($"I am {Name}, studying {Course} at Your IT Tutor. Mark: {Mark}%");
}

var l = new Learner("Thandi", 21, "C#", 74.5);
l.Introduce();  // calls overridden version

Person p = l;   // upcasting — Learner IS-A Person
p.Introduce();  // polymorphic — still calls Learner version

virtual vs sealed

CSHARP — sealed and type checking
// sealed prevents further overriding:
public class Learner : Person {
    public sealed override void Introduce() =>
        Console.WriteLine($"Sealed — cannot be further overridden.");
}

// sealed class — cannot be derived from at all:
public sealed class FinalClass { }

// Checking type at runtime:
Person p = new Learner("Sipho", 24, "Java", 81.0);
Console.WriteLine(p is Learner);       // True
Console.WriteLine(p.GetType().Name);   // Learner

Practice Task

Your Turn

Create hierarchy: Animal (name, virtual Speak()), Dog : Animal (override Speak to bark), Cat : Animal (override Speak to meow), GuideDog : Dog (override Speak, sealed). Store all in Animal[] and call Speak() on each. Try inheriting from GuideDog — observe the compile error.

Common Mistakes

  • Forgetting virtual on the parent method — without it, the child method hides rather than overrides, breaking polymorphism.
  • Using Java's extends — C# uses :.
  • Using Java's super — C# uses base.
  • Deep inheritance chains — three levels maximum in practice.

Professional Tip

The virtual/override requirement is intentional — it makes the design explicit. A parent method that is not virtual says 'this is not designed to be overridden'. Removing virtual to add it later is a breaking change.

Mini Quiz

What must a C# parent method have before it can be overridden?