Lesson 18 — Contracts

Interfaces

C# interfaces define contracts prefixed with I by convention. Default interface methods (C# 8+) allow evolution without breaking implementors.

CSHARP — Interface and implementation
// Interface — defines what, not how:
public interface IPrintable {
    void PrintReport();  // abstract by default
    string GetSummary(); // abstract by default

    // Default method (C# 8+) — has a body, implementors inherit it:
    void PrintToConsole() {
        Console.WriteLine("--- Report ---");
        Console.WriteLine(GetSummary());
        Console.WriteLine("--------------");
    }
}

// A class can implement multiple interfaces:
public class Learner : Person, IPrintable, IComparable<Learner> {
    public void PrintReport() =>
        Console.WriteLine($"Learner Report: {Name} | {Course} | {Mark:F1}%");

    public string GetSummary() =>
        $"{Name}: {Mark:F1}% ({GradeLabel()})";

    public int CompareTo(Learner? other) =>
        Mark.CompareTo(other?.Mark ?? 0); // sort by mark
}
CSHARP — Interface as type
// Interface as a type:
IPrintable[] items = {
    new Learner("Thandi", 21, "C#", 74.5),
    new Learner("Sipho",  24, "Java", 81.0),
};

foreach (var item in items) {
    item.PrintReport();    // abstract method
    item.PrintToConsole(); // default method
}

Practice Task

Your Turn

Create interfaces: ICertifiable (GenerateCertificate() returns string), IGradeable (GetGradeLabel() returns string, default PrintGrade() calls it), IExportable (ToCSV() returns string). Implement all three in Learner, only ICertifiable in Facilitator. Write ExportAll(IExportable[]) and CertifyAll(ICertifiable[]). Test with mixed arrays.

Common Mistakes

  • Interface methods are public by default — do not add public.
  • Implementing an interface with extends instead of : (syntax error).
  • Missing @Override equivalent (override keyword) when implementing.
  • Interface names must start with I in .NET convention.

Professional Tip

Design to interfaces, not implementations. If a method only needs printing behaviour, accept IPrintable not Learner. This future-proofs your code for any type that implements the interface.

Mini Quiz

C# interface names conventionally start with?