An abstract class can share code while requiring derived classes to fill in a method.

abstract class An abstract class can define shared behavior and abstract members.

Abstract Classes

count
AbstractClasses.cs
Replay: real traced execution (multi-file project)
using System;

abstract class Report
{
    public string Title { get; }

    protected Report(string title)
    {
        Title = title;
    }

    public abstract string Body();

    public string Summary()
    {
        return Title + ":" + Body();
    }
}

class CountReport : Report
{
    private readonly int count;

    public CountReport(string title, int count) : base(title)
    {
        this.count = count;
    }

    public override string Body()
    {
        return count + " items";
    }
}

class Program
{
    static void Main()
    {
        int count = 3;
        Report report = new CountReport("daily", count);
        string summary = report.Summary();

        Console.WriteLine($"count={count}");
        Console.WriteLine($"summary={summary}");
    }
}
using System;

abstract class Report
{
    public string Title { get; }

    protected Report(string title)
    {
        Title = title;
    }

    public abstract string Body();

    public string Summary()
    {
        return Title + ":" + Body();
    }
}

class CountReport : Report
{
    private readonly int count;

    public CountReport(string title, int count) : base(title)
    {
        this.count = count;
    }

    public override string Body()
    {
        return count + " items";
    }
}

class Program
{
    static void Main()
    {
        int count = 1;
        Report report = new CountReport("daily", count);
        string summary = report.Summary();

        Console.WriteLine($"count={count}");
        Console.WriteLine($"summary={summary}");
    }
}
using System;

abstract class Report
{
    public string Title { get; }

    protected Report(string title)
    {
        Title = title;
    }

    public abstract string Body();

    public string Summary()
    {
        return Title + ":" + Body();
    }
}

class CountReport : Report
{
    private readonly int count;

    public CountReport(string title, int count) : base(title)
    {
        this.count = count;
    }

    public override string Body()
    {
        return count + " items";
    }
}

class Program
{
    static void Main()
    {
        int count = 5;
        Report report = new CountReport("daily", count);
        string summary = report.Summary();

        Console.WriteLine($"count={count}");
        Console.WriteLine($"summary={summary}");
    }
}
  1. count ← 3

    36{37    static void Main()38    {39        int count→ 3 = 3; //@count=1, 540        Report report = new CountReport("daily", count);41        string summary = report.Summary();
  2. protected Report(string title)

    7protected Report(string titledaily)8{9    Title = titledaily;10}
  3. this.count ← 3

    24public CountReport(string titledaily, int count3) : base(title)25{26    this.count→ 3 = count3;27}
  4. report ← CountReport

    39int count = 3; //@count=1, 540Report report→ CountReport = new CountReport("daily", count);41string summary = reportCountReport.Summary();
  5. public override string Body()

    29public override string Body()30{31    return count3 + " items";32}
  6. summary ← daily:3 items

    40    Report report = new CountReport("daily", count);41    string summary→ daily:3 items = reportCountReport.Summary();4243    Console.WriteLine($"count={count3}");44    Console.WriteLine($"summary={summarydaily:3 items}");45}
    outputcount=3
    summary=daily:3 items
  1. count ← 1

    36{37    static void Main()38    {39        int count→ 1 = 1;40        Report report = new CountReport("daily", count);41        string summary = report.Summary();
  2. protected Report(string title)

    7protected Report(string titledaily)8{9    Title = titledaily;10}
  3. this.count ← 1

    24public CountReport(string titledaily, int count1) : base(title)25{26    this.count→ 1 = count1;27}
  4. report ← CountReport

    39int count = 1;40Report report→ CountReport = new CountReport("daily", count);41string summary = reportCountReport.Summary();
  5. public override string Body()

    29public override string Body()30{31    return count1 + " items";32}
  6. summary ← daily:1 items

    40    Report report = new CountReport("daily", count);41    string summary→ daily:1 items = reportCountReport.Summary();4243    Console.WriteLine($"count={count1}");44    Console.WriteLine($"summary={summarydaily:1 items}");45}
    outputcount=1
    summary=daily:1 items
  1. count ← 5

    36{37    static void Main()38    {39        int count→ 5 = 5;40        Report report = new CountReport("daily", count);41        string summary = report.Summary();
  2. protected Report(string title)

    7protected Report(string titledaily)8{9    Title = titledaily;10}
  3. this.count ← 5

    24public CountReport(string titledaily, int count5) : base(title)25{26    this.count→ 5 = count5;27}
  4. report ← CountReport

    39int count = 5;40Report report→ CountReport = new CountReport("daily", count);41string summary = reportCountReport.Summary();
  5. public override string Body()

    29public override string Body()30{31    return count5 + " items";32}
  6. summary ← daily:5 items

    40    Report report = new CountReport("daily", count);41    string summary→ daily:5 items = reportCountReport.Summary();4243    Console.WriteLine($"count={count5}");44    Console.WriteLine($"summary={summarydaily:5 items}");45}
    outputcount=5
    summary=daily:5 items