<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. C#
  3. Object-oriented programming
All lessons in this course

Lesson 24 of 60 12 minIntermediate

Abstract classes

Base classes that describe an idea but can’t be created themselves, with abstract members every child must implement.

What is the area of “a shape”? There is no answer until you know which shape. Some base classes represent an idea, not a real thing. Mark them abstract: they can’t be created with new, and they can declare abstract members that every concrete child must implement.

Shapes.cs
public abstract class Shape{    public string Name { get; }    protected Shape(string name) => Name = name;     public abstract double Area();          // no body: children MUST provide it     public override string ToString() => $"{Name}: {Area():F2}";   // normal method using it} public class Rectangle : Shape{    public double Width { get; }    public double Height { get; }    public Rectangle(double w, double h) : base("Rectangle") { Width = w; Height = h; }    public override double Area() => Width * Height;} public class Circle : Shape{    public double Radius { get; }    public Circle(double r) : base("Circle") => Radius = r;    public override double Area() => Math.PI * Radius * Radius;} var shapes = new List<Shape> { new Rectangle(4, 3), new Circle(1.5) };foreach (var s in shapes) Console.WriteLine(s);// var x = new Shape("?");   // error CS0144: cannot create an abstract class
Output
Rectangle: 12.00
Circle: 7.07
Interactive

Abstract base, concrete shapes

Add shapes to a List<Shape>. Each one must implement the abstract Area() in its own way. Then try to create a plain Shape.

new Rectangle(4, 3)
Area() → Width × Height
12.00
new Triangle(6, 2)
Area() → ½ × Base × Height
6.00
foreach (Shape s in shapes) total += s.Area(); → total = 18.00

The rules

  • An abstract class can’t be instantiated, but it can have constructors (called by children through base(...)), fields, properties and normal methods.
  • An abstract method has no body and is implicitly virtual. Only abstract classes can contain abstract members.
  • A non-abstract child must override every abstract member, or the code won’t compile (CS0534).
  • You can still use the abstract type for variables, parameters and lists: List<Shape>.

The template method pattern

A powerful use of abstract classes: the base class defines the steps of an algorithm and children fill in the details.

Exporter.cs
public abstract class ReportExporter{    // the fixed overall process    public void Export(string path)    {        string body = BuildBody();        File.WriteAllText(path, Header() + body + Footer());        Console.WriteLine($"Saved {path}");    }     protected virtual string Header() => "Steel Report\n";    // optional to change    protected abstract string BuildBody();                     // must be supplied    protected virtual string Footer() => "\n-- end --";} public class CsvExporter : ReportExporter{    protected override string BuildBody() => "Mark,Length\nB1,6.0\n";} new CsvExporter().Export("report.csv");
Output
Saved report.csv

virtual vs abstract

`virtual``abstract`
Has a body?Yes, a default implementationNo
Child must override?No, optionalYes, required
Allowed inAny non-sealed classAbstract classes only
Quick check

What happens with new Shape() when Shape is abstract?

Quick check

A class inherits from an abstract class but doesn’t implement one abstract method. What must be true for it to compile?

Practice

Create an abstract class Vehicle with a Name and an abstract method double CostPerKm(), plus a normal method double TripCost(double km) that uses it. Implement Truck (₹28 / km) and Car (₹9 / km), and print the cost of a 120 km trip for each.

Show the solution
Solution.cs
public abstract class Vehicle{    public string Name { get; }    protected Vehicle(string name) => Name = name;    public abstract double CostPerKm();    public double TripCost(double km) => km * CostPerKm();} public class Truck : Vehicle{    public Truck() : base("Truck") { }    public override double CostPerKm() => 28;} public class Car : Vehicle{    public Car() : base("Car") { }    public override double CostPerKm() => 9;} foreach (Vehicle v in new Vehicle[] { new Truck(), new Car() })    Console.WriteLine($"{v.Name}: Rs {v.TripCost(120)}");
Output
Truck: Rs 3360
Car: Rs 1080

Remember

  • An abstract class is an incomplete base class; you can’t new it.
  • Abstract members have no body and must be overridden by concrete children.
  • Abstract classes can still hold shared fields, constructors and methods.
  • Use them when related classes share code but each must fill in some parts.
0 of 60 lessons completed