Interfaces & Abstract Classes
What Is an Interface?
An interface is a contract. It says "if you sign this contract, you promise to have these methods and properties." It doesn't tell you how to do them — just that you must do them.
Think of it like a job description. A "driver" must be able to StartEngine(), Steer(), and Stop(). Whether they're driving a car, bus, or spaceship doesn't matter — they all fulfill the same contract.
Why is this useful? Because you can write code that works with any object that implements the interface, without caring about its specific type. Your code just says "give me something that can drive" and it works with cars, buses, and spaceships.
Defining & Implementing Interfaces
Multiple Interfaces — Wear Many Hats
A class can only inherit from one parent class (single inheritance), but it can implement as many interfaces as it wants. Built-in interfaces like IComparable are what power sorted data structures such as binary search trees. It's like a person who is both a "swimmer" AND a "runner" AND a "cook" — they fulfill all those contracts simultaneously.
Since C# 8, interfaces can also have default implementations — meaning you can provide a method body right in the interface. Classes that implement the interface get that method for free but can still override it if they want.
Multiple Interfaces & Default Methods
Abstract Class vs Interface — When to Use Which?
They seem similar, so here's the cheat sheet:
- Interface: Pure contract. No state (until C# 8 defaults). A class can implement many. Use when unrelated classes need the same capability (like IPrintable).
- Abstract class: Partial blueprint. Can have fields, constructors, and both implemented AND abstract methods. A class can inherit only one. Use when classes share a common identity (like all Shapes).
Rule of thumb: If it's a "can do" relationship (can print, can save), use an interface. If it's an "is a" relationship (is a shape, is an animal), use an abstract class.