Search code examples
c#inheritanceabstract-classmultiple-inheritance

How to organise abstract class hierarchy in C#


I have a situation in C# when I need multiple inheritance in order to not double code in implementation class, but that's forbidden in C#.

What should I do?

I have the following interfaces:

public interface ICar
{
   void Move();
   void GetService();
}

public interface ISuperCar : ICar
{
   void MoveFast();
   void HaveARace();
}

And abstract classes:

public abstract class Car : ICar
{
   public void Move()
   {
      Console.WriteLine("Car moves");
   }

   public abstract void GetService();
}

public abstract class SuperCar : Car, ISuperCar
{
   public void MoveFast()
   {
      Console.WriteLine("SuperCar moves fastly");
   }

   public abstract void HaveARace();
}

And their implementations:

public class ToyotaCar : Car
{
   public override void GetService()
   {
      Console.WriteLine("Getting ToyotaService");
   }
}

public class ToyotaSuperCar : SuperCar
{
   public override void GetService()
   {
      Console.WriteLine("Getting ToyotaService");
   }

   public override void HaveARace()
   {
      Console.WriteLine("Have a race in Toyota competition");
   }
}

And the question is how not to double method GetService(). Logically it should by:

public class ToyotaSuperCar : SuperCar, ToyotaCar
{
   public override void HaveARace()
   {
      Console.WriteLine("Have a race in Toyota competition");
   }
}

But multiple inheritance is not available in C#


Solution

  • You could use composition instead of inheritance. Make your SuperCar class implement ICar instead of inheriting from Car and pass an ICar object in the constructor to which you delegate the methods:

    public abstract class SuperCar : ICar, ISuperCar
    {
        private readonly ICar car;
    
        public SuperCar(ICar car)
        {
            this.car = car;
        }
    
        public void Move() => car.Move();
    
        public void GetService() => car.GetService();
    
        public void MoveFast()
        {
            Console.WriteLine("SuperCar moves fastly");
        }
    
       public abstract void HaveARace();
    }
    

    Your ToyotaSuperCar class would then look like so:

    public class ToyotaSuperCar : SuperCar
    {
        public ToyotaSuperCar(ToyotaCar car) : base(car) { }
    
        public override void HaveARace()
        {
           Console.WriteLine("Have a race in Toyota competition");
        }
    }