C# Interface
Defining contracts for classes to implement
🔌 What is an Interface?
An interface is a contract that defines a set of methods and properties without implementation. Classes that implement an interface must provide implementations for all its members.
interface IAnimal {
void MakeSound();
void Move();
}
class Dog : IAnimal {
public void MakeSound() {
Console.WriteLine("Woof!");
}
public void Move() {
Console.WriteLine("Running...");
}
}
Output:
Woof!
Running...
Key Interface Concepts
Contract
Defines what must be implemented
interface IShape {
double GetArea();
}
Multiple Interfaces
Class can implement many
class Car : IVehicle,
IElectric { }
No Implementation
Only method signatures
void Start();
void Stop();
Must Implement All
All members are required
public void Start() {
// required
}
🔹 Basic Interface Example
An interface defines a contract—method signatures, properties, or events—without implementation. A Car class implementing an IVehicle interface must provide concrete methods for Start, Stop, and a Speed property. Interfaces enable polymorphism and loose coupling; code can depend on IVehicle rather than a specific class. This is foundational for dependency injection and designing flexible, modular systems.
interface IVehicle {
void Start();
void Stop();
int GetSpeed();
}
class Car : IVehicle {
private int speed = 0;
public void Start() {
Console.WriteLine("Car started");
speed = 50;
}
public void Stop() {
Console.WriteLine("Car stopped");
speed = 0;
}
public int GetSpeed() {
return speed;
}
}
// Usage
IVehicle myCar = new Car();
myCar.Start();
Console.WriteLine($"Speed: {myCar.GetSpeed()} km/h");
myCar.Stop();
Output:
Car started
Speed: 50 km/h
Car stopped
🔹 Multiple Interface Implementation
A single class can implement multiple interfaces, combining capabilities from different contracts. A SmartDevice might implement both IPlayable and IRecordable. This supports granular, role-based design without the limitations of single inheritance. Interfaces allow classes to fulfill diverse responsibilities, promoting flexibility and composition over inheritance. It's a common pattern in media players and plugin architectures.
interface IPlayable {
void Play();
}
interface IRecordable {
void Record();
}
class MediaPlayer : IPlayable, IRecordable {
public void Play() {
Console.WriteLine("Playing media...");
}
public void Record() {
Console.WriteLine("Recording media...");
}
}
// Usage
MediaPlayer player = new MediaPlayer();
player.Play();
player.Record();
Output:
Playing media...
Recording media...
🔹 Interface with Properties
Interfaces can declare properties, requiring implementing classes to define getters and setters. An IPerson interface might mandate Name and Age properties, ensuring consistent data access. A Student class then provides these properties alongside additional members like School. This enforces a uniform structure across different implementations, facilitating code that works with IPerson references and guaranteed property availability.
interface IPerson {
string Name { get; set; }
int Age { get; set; }
void Introduce();
}
class Student : IPerson {
public string Name { get; set; }
public int Age { get; set; }
public string School { get; set; }
public void Introduce() {
Console.WriteLine($"Hi, I'm {Name}, {Age} years old");
Console.WriteLine($"I study at {School}");
}
}
// Usage
IPerson student = new Student {
Name = "Emma",
Age = 20,
School = "MIT"
};
student.Introduce();
Output:
Hi, I'm Emma, 20 years old
I study at MIT
🔹 Interface Inheritance
Interfaces can inherit from other interfaces, forming a hierarchy of contracts. IColoredShape might inherit from IShape, adding a Color property. A class implementing IColoredShape must satisfy both interfaces. This allows for specialized, incremental contracts and avoids bloating a single interface. It's used in graphics libraries and API design to create layered abstractions.
interface IShape {
double GetArea();
}
interface IColoredShape : IShape {
string GetColor();
}
class Circle : IColoredShape {
public double Radius = 5;
public string Color = "Red";
public double GetArea() {
return 3.14 * Radius * Radius;
}
public string GetColor() {
return Color;
}
}
// Usage
IColoredShape circle = new Circle();
Console.WriteLine($"Area: {circle.GetArea()}");
Console.WriteLine($"Color: {circle.GetColor()}");
Output:
Area: 78.5
Color: Red
🔹 Real-World Example
Interfaces enable dependency injection and loosely coupled architectures. In payment processing, an IPaymentGateway interface allows switching between CreditCardProcessor or PayPalProcessor without changing core logic. The system validates and processes payments through the interface, adhering to the Open/Closed Principle. This makes applications testable, maintainable, and adaptable to new payment methods.
interface IPaymentProcessor {
void ProcessPayment(double amount);
bool ValidatePayment();
}
class CreditCardProcessor : IPaymentProcessor {
public void ProcessPayment(double amount) {
Console.WriteLine($"Processing ${amount} via Credit Card");
}
public bool ValidatePayment() {
Console.WriteLine("Credit card validated");
return true;
}
}
class PayPalProcessor : IPaymentProcessor {
public void ProcessPayment(double amount) {
Console.WriteLine($"Processing ${amount} via PayPal");
}
public bool ValidatePayment() {
Console.WriteLine("PayPal account validated");
return true;
}
}
// Usage
IPaymentProcessor payment = new CreditCardProcessor();
if (payment.ValidatePayment()) {
payment.ProcessPayment(99.99);
}
Output:
Credit card validated
Processing $99.99 via Credit Card