Title: Provide multiple inheritance in C#
Sometimes you might want a class to inherit from more than one parent class. For example, you might define a Vehicle class that has vehicle properties such as MaxSpeed, and a Domicile class with house-like properties such as SquareFeet. You might then like to make a HouseBoat or MotorHome class that inherits from both Vehicle and Domicile.
Unfortunately C# does not allow multiple inheritance. A class can inherit from at most one parent class. However, a class can implement any number of interfaces so, instead of true multiple inheritance, you can use interface inheritance. In this example, you can make HouseBoat inherit from Domicile and implement the IVehicle interface.
Even if you make HouseBoat implement IVehicle, it doesn't really inherit from a Vehicle class. That means it cannot inherit code to provide the IVehicle features.
Fortunately there's a workaround. To solve that problem, you can make a class that implements the interface and that does nothing else. Then you can delegate interface features to a private instance of that class. This example uses a Vehicle class to implement IVehicle.
Here's the IVehicle interface.
public interface IVehicle
{
// Define a MaxSpeed property.
int MaxSpeed { get; set; }
}
The interface just defines the MaxSpeed property.
Here's the Vehicle class that implements IVehicle.
public class Vehicle : IVehicle
{
// Implement IVehicle.MaxSpeed
private int _MaxSpeed;
public int MaxSpeed
{
get { return _MaxSpeed; }
set { _MaxSpeed = value; }
}
}
The Vehicle class uses a private backing field to implement the MaxSpeed property.
The following code defines the Domicile class.
public class Domicile
{
private int _SquareFeet;
public int SquareFeet
{
get { return _SquareFeet; }
set { _SquareFeet = value; }
}
}
This class just defines a SquareFeet property.
Now the HouseBoat class inherits from Domicile and implements IVehicle as shown in the following code.
public class HouseBoat : Domicile, IVehicle
{
// Inherits the SquareFeet property from Domicile.
// Delegate IVehicle features to a Vehicle object.
private Vehicle _Vehicle = new Vehicle();
public int MaxSpeed
{
get { return _Vehicle.MaxSpeed; }
set { _Vehicle.MaxSpeed = value; }
}
}
The class automatically gets the SquareFeet property defined by the Domicile class via inheritance.
The biggest trick here is that the class includes a private Vehicle object and delegates all of the IVehicle members to that object. In this example, it implements the MaxSpeed property by using the Vehicle object's MaxSpeed property. That lets it reuse the code in the Vehicle class in a manner that is somewhat similar to inheritance, at least when seen from the outside.
If you need to override the MaxSpeed property, you can do so by making the HouseBoat class provide its own version instead of delegating the property to its private Vehicle object.
The main program uses the following code to demonstrate the HouseBoat class.
// Make some objects.
private void Form1_Load(object sender, EventArgs e)
{
// Make a HouseBoat.
HouseBoat boat = new HouseBoat();
boat.SquareFeet = 100;
boat.MaxSpeed = 10;
// Make an IVehicle variable.
IVehicle ivehicle = boat;
ivehicle.MaxSpeed = 15;
}
The code first makes a HouseBoat object and sets its SquareFeet and MaxSpeed properties. If then makes an IVehicle variable referring to the same object and uses the new variable to set its MaxSpeed property to a new value.
To summarize, the steps for this kind of multiple inheritance are:
- Make the parent class (Domicile)
- Make the interface (IVehicle)
- Define the actual interface (IVehicle)
- Make a class that implements the interface (Vehicle)
- Make the child class (HouseBoat)
- Make the child class inherit from the parent class (Domicile)
- Make the child class create a private instance of the interface implementing class (Vehicle)
- Make the child class implement the interface by delegating members to the private instance
Yes this is all a bit roundabout but it gives the appearance of multiple inheritance from the point of view of the code that uses the HouseBoat class. If you modify the Domicile class, HouseBoat automatically inherits the changes. If you change the implementation code in the Vehicle class, HouseBoat picks up those changes, too.
The catch is that if you modify the IVehicle interface, you need to update the Vehicle class and possibly the HouseBoat class.
Download the example to experiment with it and to see additional details.
|