An interface is essentially a collection of definitions that a class or a structure can implement (such as methods, properties, events, or indexers).
Unlike classes, interfaces do not contain method implementations, they only define the members that must be implemented by the classes or structures that implement them.
Interfaces are fundamental in object-oriented programming because they allow you to define functionalities and behaviors that can be implemented by different classes, and they promote code maintainability and reusability.
If you want to learn more, check out the Object-Oriented Programming Course
Interfaces in C#
An interface is declared using the interface keyword.
[modifier] interface InterfaceName
{
// Method definition
dataType MethodName(parameters);
// Property definition
dataType PropertyName { get; set; }
}
- InterfaceName: The unique name given to the interface.
- Modifier: Can be
publicorinternalto define the access level of the interface. - returnType: Specifies the data type of properties and methods.
MethodName,PropertyName: These are the unique identifiers for methods, properties, and events respectively.- parameters: These are the variables used to pass information to the method when it is called.
Implementing Interfaces
To implement an interface in a class use the colon (:) syntax followed by the interface name. The class must provide implementations for all members defined in the interface.
Here is an example of how to define and implement an interface in C#:
public interface IDriveable
{
string LicensePlate { get; set; }
// Methods
void Drive();
void Brake();
}
public class Car : IDriveable
{
// Implementation of properties
public string LicensePlate { get; set; }
// Implementation of methods
public void Drive()
{
Console.WriteLine("The car is driving.");
}
public void Brake()
{
Console.WriteLine("The car has stopped.");
}
}
In this example:
- An
IVehicleinterface is defined with a property (LicensePlate) and two methods (DriveandBrake). - The
Carclass implements theIVehicleinterface and provides the implementation for all its properties and methods.
Polymorphism with Interfaces
One of the most important features of interfaces is their ability to support polymorphism. This allows an instance of a class that implements an interface to be treated as an instance of that interface.
Suppose we have another class that implements IDriveable called Bicycle.
public class Bicycle : IDriveable
{
// implementation
}
Now we can define a variable of type IDriveable, and assign variables of type Car or Bicycle.
IDriveable vehicle;
vehicle = new Car();
vehicle.Start(); // Output: The car has started.
vehicle.Stop(); // Output: The car has stopped.
vehicle = new Bicycle();
vehicle.Start(); // Output: The bicycle has started moving.
vehicle.Stop(); // Output: The bicycle has stopped.
Implementing Multiple Interfaces
C# does not support direct multiple inheritance (a class derived from multiple base classes). However, a class can implement multiple interfaces, which provides a way to achieve behavior similar to multiple inheritance.
For example, in this example, the Duck class implements the IFlyable and ISwimmable interfaces.
public interface IFlyable
{
void Fly();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IFlyable, ISwimmable
{
public void Fly()
{
Console.WriteLine("The duck is flying.");
}
public void Swim()
{
Console.WriteLine("The duck is swimming.");
}
}
Explicit Implementation
C# allows explicit implementation of interface members. This is useful when a class implements multiple interfaces that may have methods with the same name, or when you want to provide specific implementations that are not directly accessible through the class.
In this example, the Multifunctional class implements the IPrintable and IScannable interfaces. But both interfaces declare a Print() method. We can explicitly declare the interfaces to resolve the naming conflict.
public interface IPrintable
{
void Print();
}
public interface IScannable
{
void Print();
}
public class Multifunctional : IPrintable, IScannable
{
void IPrintable.Print()
{
Console.WriteLine("Printing...");
}
void IScannable.Print()
{
Console.WriteLine("Scanning...");
}
}
// Usage
IPrintable printer = new Multifunctional();
printer.Print(); // Output: Printing...
IScannable scanner = new Multifunctional();
scanner.Print(); // Output: Scanning...
Practical Examples
Representing an Electronic Device
This IPowerable interface defines the methods an electronic device must have. The Phone class implements this interface:
public interface IPowerable
{
// Methods
void PowerOn();
void PowerOff();
void Restart();
}
public class Phone : IPowerable
{
// Implementation of methods
public void PowerOn()
{
Console.WriteLine("The phone is powering on.");
}
public void PowerOff()
{
Console.WriteLine("The phone is powering off.");
}
public void Restart()
{
Console.WriteLine("The phone is restarting.");
}
}
Communication Behavior
This ICommunicator interface defines the methods a communication device must have. The Phone class implements this interface, while also maintaining IPowerable.
public interface ICommunicator
{
// Methods
void Call(string number);
void SendMessage(string number, string message);
}
public class Phone : ICommunicator, IPowerable
{
// ... IPowerable code from previous example ... //
// Implementation of ICommunicator methods
public void Call(string number)
{
Console.WriteLine($"Calling number {number}.");
}
public void SendMessage(string number, string message)
{
Console.WriteLine($"Sending message to number {number}: {message}");
}
}
Payment Behavior
This IPayments interface defines the methods a payment system must have. The ElectronicPayment class implements this interface:
public interface IPayments
{
// Methods
void ProcessPayment(decimal amount);
void RefundPayment(decimal amount);
}
public class ElectronicPayment : IPayments
{
// Implementation of methods
public void ProcessPayment(decimal amount)
{
Console.WriteLine($"Processing payment of {amount}.");
}
public void RefundPayment(decimal amount)
{
Console.WriteLine($"Refunding payment of {amount}.");
}
}
