C# > Object-Oriented Programming (OOP) > Abstraction > Interfaces vs Abstract Classes
Interfaces vs. Abstract Classes: Defining Vehicle Behavior
This example demonstrates the differences between interfaces and abstract classes in C# by defining a common 'Vehicle' concept and implementing it using both approaches. It highlights when to use each based on the desired level of implementation and flexibility.
Introduction to Abstraction: Vehicle Example
Abstraction is a key principle of OOP that involves hiding complex implementation details and exposing only the essential information to the user. We will implement the Vehicle concept using both interfaces and abstract classes. This example will highlight the similarities and differences between the two constructs.
Defining the IVehicle Interface
The `IVehicle` interface defines a contract that any implementing class must adhere to. It specifies that a vehicle must have `Start`, `Stop`, and `GetDescription` methods. Interfaces define *what* a class should do, but not *how*.
public interface IVehicle
{
void Start();
void Stop();
string GetDescription();
}
Implementing the IVehicle Interface: Car
The `Car` class implements the `IVehicle` interface. This means it *must* provide implementations for all the members defined in the `IVehicle` interface. The `Car` class provides concrete implementations for `Start`, `Stop`, and `GetDescription`, specific to a car.
public class Car : IVehicle
{
public string Model { get; set; }
public Car(string model)
{
Model = model;
}
public void Start()
{
Console.WriteLine("Car starting...");
}
public void Stop()
{
Console.WriteLine("Car stopping...");
}
public string GetDescription()
{
return $"Car: {Model}";
}
}
Defining the Abstract Vehicle Class
The `AbstractVehicle` class is an abstract class that defines a common base for vehicles. It includes an abstract `Start` and `Stop` method (which *must* be implemented by derived classes) and a concrete `GetDescription` method with a default implementation and `GetBrand` method. Abstract classes can contain both abstract methods (without implementation) and concrete methods (with implementation). They can also contain fields (like `Brand`).
public abstract class AbstractVehicle
{
public string Brand { get; set; }
public abstract void Start();
public abstract void Stop();
public string GetBrand() {
return $"Brand: {Brand}";
}
public virtual string GetDescription()
{
return $"Vehicle Description from AbstractVehicle";
}
}
Implementing the Abstract Vehicle Class: Motorcycle
The `Motorcycle` class inherits from `AbstractVehicle`. It *must* override the abstract methods `Start` and `Stop` to provide concrete implementations. It also overrides the `GetDescription` method to provide a more specific description for a motorcycle. This demonstrates the use of inheritance and polymorphism.
public class Motorcycle : AbstractVehicle
{
public int EngineDisplacement { get; set; }
public override void Start()
{
Console.WriteLine("Motorcycle starting...");
}
public override void Stop()
{
Console.WriteLine("Motorcycle stopping...");
}
public override string GetDescription()
{
return $"Motorcycle: {Brand}, {EngineDisplacement}cc";
}
}
Demonstrating Usage
This code demonstrates how to create instances of the `Car` and `Motorcycle` classes and call their methods. It highlights the use of both the interface and abstract class types.
IVehicle myCar = new Car("Tesla Model S");
myCar.Start();
Console.WriteLine(myCar.GetDescription());
myCar.Stop();
AbstractVehicle myMotorcycle = new Motorcycle();
myMotorcycle.Brand = "Harley-Davidson";
((Motorcycle)myMotorcycle).EngineDisplacement = 1200; // Need to cast to access Motorcycle specific property
myMotorcycle.Start();
Console.WriteLine(myMotorcycle.GetDescription());
Console.WriteLine(myMotorcycle.GetBrand());
myMotorcycle.Stop();
Concepts Behind the Snippet
This snippet demonstrates the core concepts of:
Real-Life Use Case
Consider a software system for managing various types of equipment in a factory. You might use an interface like `IEquipment` to define common actions like `TurnOn`, `TurnOff`, and `CheckStatus`. Different equipment types (e.g., `DrillPress`, `ConveyorBelt`) would implement this interface. An abstract class might be used to define the base characteristics of `PoweredEquipment` providing a base implementation and requiring derived class to implement specific behaviour.
Best Practices
Interview Tip
Be prepared to explain the difference between interfaces and abstract classes, and when to use each. Common interview questions include: 'What are the benefits of using interfaces?', 'When would you choose an abstract class over an interface?', and 'Can a class implement multiple interfaces and inherit from multiple abstract classes?'
When to Use Them
Memory Footprint
Interfaces themselves do not directly consume memory at runtime. However, classes implementing interfaces will consume memory based on their fields and the implementation of interface methods. Abstract classes have a larger memory footprint because they can contain data fields and method implementations.
Alternatives
Pros and Cons
Interfaces
Abstract Classes
FAQ
-
What is the main difference between an interface and an abstract class?
An interface defines a contract that classes must implement, providing no implementation details. An abstract class can provide some implementation and requires derived classes to implement specific methods. -
Can a class implement multiple interfaces?
Yes, a class can implement multiple interfaces, allowing for multiple inheritance-like behavior. -
Can a class inherit from multiple abstract classes?
No, a class can only inherit from one abstract class in C#. -
When should I use an interface instead of an abstract class?
Use an interface when you need maximum flexibility and want to define a contract that multiple unrelated classes can implement. Use an abstract class when you want to provide a common base implementation and enforce a certain structure on derived classes.