Understanding Interfaces in C#
Interfaces are a fundamental concept in object-oriented programming, and C# provides robust support for them. An interface is a contract that defines a set of members (methods, properties, events, and indexers) that a class must implement. It specifies what a class can do, but not how it does it.
What is an Interface?
Think of an interface as a blueprint for behavior. It outlines the methods that a class will provide without giving any implementation details. A class that implements an interface is obligated to provide concrete implementations for all the members declared in that interface.
Key Characteristics of Interfaces:
- Abstraction: Interfaces provide a high level of abstraction, hiding implementation details.
- Polymorphism: They enable polymorphism, allowing objects of different classes to be treated as objects of a common interface type.
- Multiple Inheritance of Type: A class can implement multiple interfaces, achieving a form of multiple inheritance of type (but not implementation).
- No Implementation: Interfaces themselves do not contain implementation code.
- Public by Default: All members of an interface are implicitly public.
Defining an Interface
You define an interface using the interface
keyword. It's a common convention to prefix interface names with a capital 'I'.
public interface IDrivable
{
void StartEngine();
void Accelerate();
void Brake();
int CurrentSpeed { get; }
}
Implementing an Interface
To implement an interface, a class declares that it implements the interface and provides implementations for all its members.
Example: Implementing the IDrivable Interface
public class Car : IDrivable
{
private int speed = 0;
public void StartEngine()
{
Console.WriteLine("Car engine started.");
}
public void Accelerate()
{
speed += 10;
Console.WriteLine($"Accelerating. Current speed: {speed} km/h");
}
public void Brake()
{
speed -= 5;
if (speed < 0) speed = 0;
Console.WriteLine($"Braking. Current speed: {speed} km/h");
}
public int CurrentSpeed
{
get { return speed; }
}
}
Using Interfaces
You can declare variables of an interface type and assign objects of classes that implement the interface. This allows for flexible code that can work with any object implementing a specific contract.
Example: Demonstrating Interface Usage
IDrivable myVehicle = new Car();
myVehicle.StartEngine();
myVehicle.Accelerate();
myVehicle.Accelerate();
myVehicle.Brake();
Console.WriteLine($"Final speed: {myVehicle.CurrentSpeed}");
Why Use Interfaces?
- Decoupling: They decouple the caller from the specific implementation, making code more modular and maintainable.
- Testability: Interfaces make it easier to write unit tests by allowing you to mock dependencies.
- Design Flexibility: They provide flexibility in designing your application architecture.
- API Contracts: They define clear contracts for libraries and frameworks.
Interface Inheritance
Interfaces can also inherit from other interfaces, combining their contracts.
public interface IElectricVehicle : IDrivable
{
void ChargeBattery();
int BatteryLevel { get; }
}
public class ElectricCar : IElectricVehicle
{
// Implementations for IDrivable...
public void StartEngine() { Console.WriteLine("Electric car powered on."); }
public void Accelerate() { /* ... */ }
public void Brake() { /* ... */ }
public int CurrentSpeed { get { return 0; } } // Placeholder
// Implementations for IElectricVehicle
public void ChargeBattery() { Console.WriteLine("Charging battery."); }
public int BatteryLevel { get { return 100; } } // Placeholder
}
Understanding and effectively using interfaces is crucial for building robust, scalable, and maintainable applications in C#.
Next Steps: Explore abstract classes and their differences from interfaces.