📋 Interfaces: The Binding Contracts
An interface is a contract. It declares what a class must do, without specifying how. When a class implements an interface, it promises to provide concrete implementations of every member the interface defines.
Think of it like a building permit: the city says "your building must have fire exits, structural inspections, and emergency lighting." The interface is the permit; the building (class) decides how to fulfill each requirement.
Declaring and Implementing Interfaces
Interfaces are declared with the interface keyword. By convention, interface names start with I (e.g., IConstructable). A class can implement multiple interfaces — this is C#'s answer to the lack of multiple inheritance.
interface IConstructable
{
void Build(); // No body — just the signature
}
interface IInspectable
{
string Inspect(); // Must return a string
}
// A class implementing BOTH interfaces
class Tower : IConstructable, IInspectable
{
public void Build()
{
Console.WriteLine("Tower is being built...");
}
public string Inspect()
{
return "Tower inspection: PASSED";
}
}
Implicit vs Explicit Implementation
Implicit implementation makes the method publicly available on the class. Explicit implementation ties the method to the interface — it's only accessible when the object is referenced as the interface type. This is useful when two interfaces have methods with the same name.
interface IPrintable
{
void Print();
}
interface ILoggable
{
void Print(); // Same method name!
}
class Report : IPrintable, ILoggable
{
// Implicit — works for IPrintable
public void Print()
{
Console.WriteLine("Printing report...");
}
// Explicit — only accessible via ILoggable reference
void ILoggable.Print()
{
Console.WriteLine("Logging report...");
}
}
// Usage:
Report r = new Report();
r.Print(); // "Printing report..."
((ILoggable)r).Print(); // "Logging report..."
Default Interface Methods (C# 8+)
Starting with C# 8, interfaces can provide default implementations. Classes that implement the interface can use the default or override it. This lets you add new methods to an interface without breaking existing implementations.
interface IDestructible
{
void Demolish();
// Default method — classes get this for free
void ScheduleDemo()
{
Console.WriteLine("Demo scheduled: Ready");
}
}
Interface Segregation Principle
Don't force classes to implement interfaces they don't need. Instead of one massive IBuilding interface with 20 methods, split it into focused contracts: IConstructable, IInspectable, IDestructible. Each class picks only the contracts it fulfills — this is the Interface Segregation Principle from SOLID.
📋 Instructions
**Your Mission: Fulfill All Building Contracts!**
Create three interfaces and a `SmartBuilding` class that implements all of them.
1. Create `IConstructable` with a method `void Build()`
2. Create `IInspectable` with a method `string Inspect()`
3. Create `IDestructible` with a default method `void ScheduleDemo()` that prints `"Demo scheduled: Ready"`
4. Create a `SmartBuilding` class that implements all three interfaces:
- Constructor takes a `string name` and stores it
- `Build()` prints `"Building {name}..."` then `"Construction: Complete!"`
- `Inspect()` returns `"Inspection: PASSED"`
5. In `Main`:
- Create a `SmartBuilding("Tower-X")`
- Call `Build()`
- Print the result of `Inspect()`
- Cast to `IDestructible` and call `ScheduleDemo()`
- Print `"All contracts fulfilled!"`
Default interface methods are only accessible through the interface type, not through the class directly. Cast your SmartBuilding to IDestructible before calling ScheduleDemo(): `((IDestructible)building).ScheduleDemo();`