Why doesn’t C# allow multiple inheritances?

Asked

Viewed 12,047 times

19

In C# we can implement several interfaces. However, because we cannot inherit from more than one base class?

3 answers

25


Inheriting many concrete classes is a major source of problems from the point of view of the design of a programming language: what to do if the two superclasses have a method of the same name? What if you have instance variables of the same name? A particularly complicated problem is diamond heritage. Consider the following inheritance pattern:

  A
 / \
B   C
 \ /
  D

A is a superclass that defines a virtual method foo(). B and C are classes inherited from A and reimplementation foo. Finally, D is a class that inherits multiple of B and C. Now, if we do

A obj = new D();
obj.foo();

which version of the method is called? The version defined in B or the one defined in C?

Due to these complications, many programming languages (including C# and Java) prefer to make things simpler and allow simple inheritance only.

That said, it may be that the language provides alternatives to some of the more common uses of multiple inheritance. For example, C# allows a class to implement more than one interface, which is similar to inheriting multiples of purely abstract classes.

  • I’ve seen programmers turn the code into a chain, creating successive inheritances until the final class (D inherits C', inherits B, inherits A, inherits Overcomes)...

6

Basically, because this would make it impossible to interoperable between languages through CLR (Common Language Runtime), because different languages define multiple inheritance of subtly different forms.

Regarding the diamond problem, referred to by @missingno, several languages have decided to include multiple inheritance, and there are several solutions to the diamond problem. C++ requires an explicit method resolution foo in class D. Scala has traits, and solves the diamond problem by the declaration order of the traits:

  • D extends B with C -> the implementation of foo in C will be used.
  • D extends C with B -> the implementation of foo in B will be used.

But in reality, the C# design team considers that in 99% of cases, multiple inheritance is not truly necessary (personally, I agree). The beginning Composition over inheritance (composition rather than heritage) is perhaps one of the most important principles of software design, and which all software engineers should know - will save your life many times throughout your career.

Having said that, there are projects that have tried to create the concept of traits in C#, as for example, the Nroles through a post-compiler, or the Heredar.

Source: Why doesn’t C# support Multiple inheritance? / Traits: How Scala Tames Multiple Inheritance

  • As another example, python solves the multiple inheritance problem by making the methods of the first declared base class prevail over the later ones (e.g., class Class(Base1, Base2):... Base1 methods will be inherited). A second point that I consider relevant, an example where multiple inheritance could be well applied would be in Xamarin to work with iOS protocols in a way close to native, since delegates are converted into abstract classes, which prevents a multiple implementation. (There are solutions implemented: Strong Delegates and Weak Delegates).

5

As the question has already been answered, I leave here an example for didactic purposes of how to implement multiple inheritance with C interfaces#.

Let’s look at the scenario.

public class Nadador
{
    public void Nadar()
    {
        Console.WriteLine("Nadador nadando...");
    }
}

public class Corredor
{
    public void Correr()
    {
        Console.WriteLine("Corredor correndo...");
    }
}

public class Ciclista
{
    public void Pedalar()
    {
        Console.WriteLine("Ciclista pedalando...");
    }
}

public class Triatleta
{
    public void Correr()
    {
        Console.WriteLine("Corredor correndo...");
    }

    public void Nadar()
    {
        Console.WriteLine("Nadador nadando...");
    }

    public void Pedalar()
    {
        Console.WriteLine("Ciclista pedalando...");
    }
}

And the test program

class Program
{
    static void TorneioDeNatacao(Nadador atleta)
    {
        atleta.Nadar();
    }

    static void TorneioDeCiclismo(Ciclista atleta)
    {
        atleta.Pedalar();
    }

    static void TorneioDeAtletismo(Corredor atleta)
    {
        atleta.Correr();
    }

    static void TorneioDeTriatlon(Triatleta atleta)
    {
        atleta.Nadar();
        atleta.Pedalar();
        atleta.Correr();
    }

    static void Main(string[] args)
    {

        Nadador nadador = new Nadador();
        Ciclista ciclista = new Ciclista();
        Corredor corredor = new Corredor();

        TorneioDeAtletismo(corredor);
        TorneioDeCiclismo(ciclista);
        TorneioDeNatacao(nadador);

        Triatleta triatleta = new Triatleta();

        TorneioDeTriatlon(triatleta);

        TorneioDeAtletismo(triatleta); //erro de compilação
        TorneioDeCiclismo(triatleta); //erro de compilação
        TorneioDeNatacao(triatleta); //erro de compilação
    }

As the Triathlete knows how to run, cycle and swim, we would like him to be able to compete in athletics, swimming and cycling competitions. How to allow this to be possible? Using interfaces, to simulate multiple inheritance.

We will also include an Iatleta interface that displays the athlete’s skills, to demonstrate polymorphism.

Follows the code:

public interface IAtleta
{
    void VerHabilidades();
}

public interface INadador : IAtleta
{
    void Nadar();
}

public interface ICorredor : IAtleta
{
    void Correr();
}

public interface ICiclista : IAtleta
{
    void Pedalar();
}

public class Atleta : IAtleta
{
    public virtual void VerHabilidades()
    {
        Console.WriteLine("Nenhuma");
    }
}

public class Nadador : Atleta, INadador
{
    public override void VerHabilidades()
    {
        Console.WriteLine("Sabe pedalar");
    }

    public void Nadar()
    {
        Console.WriteLine("Nadador nadando...");
    }
}

public class Corredor : Atleta, ICorredor
{
    public override void VerHabilidades()
    {
        Console.WriteLine("Sabe correr");
    }

    public void Correr()
    {
        Console.WriteLine("Corredor correndo...");
    }
}

public class Ciclista : Atleta, ICiclista
{
    public override void VerHabilidades()
    {
        Console.WriteLine("Sabe pedalar");
    }

    public void Pedalar()
    {
        Console.WriteLine("Ciclista pedalando...");
    }
}

public class Triatleta : Atleta, ICorredor, INadador, ICiclista
{
    public override void VerHabilidades()
    {
        Console.WriteLine("Sabe correr, pedalar e nadar");
    }

    public void Correr()
    {
        new Corredor().Correr();
    }

    public void Nadar()
    {
        new Nadador().Nadar();
    }

    public void Pedalar()
    {
        new Ciclista().Pedalar();
    }
}

Now we can change our test program, to show each athlete’s skills.

class Program
{
    static void TorneioDeNatacao(INadador atleta)
    {
        atleta.Nadar();
        atleta.VerHabilidades(); // método polimórfico
    }

    static void TorneioDeCiclismo(ICiclista atleta)
    {
        atleta.Pedalar();
        atleta.VerHabilidades(); // método polimórfico
    }

    static void TorneioDeAtletismo(ICorredor atleta)
    {
        atleta.Correr();
        atleta.VerHabilidades(); // método polimórfico
    }

    static void TorneioDeTriatlon(Triatleta atleta)
    {
        atleta.Nadar();
        atleta.Pedalar();
        atleta.Correr();
        atleta.VerHabilidades(); // método polimórfico
    }

    static void Main(string[] args)
    {

        Nadador nadador = new Nadador();
        Ciclista ciclista = new Ciclista();
        Corredor corredor = new Corredor();

        TorneioDeAtletismo(corredor);
        TorneioDeCiclismo(ciclista);
        TorneioDeNatacao(nadador);

        Triatleta triatleta = new Triatleta();

        TorneioDeAtletismo(triatleta);
        TorneioDeCiclismo(triatleta);
        TorneioDeNatacao(triatleta);
        TorneioDeTriatlon(triatleta);
    }

Now we realize that the triathlete can participate in all competitions. Even in a competition that requires only one skill, all of the triathlete’s abilities are shown by polymorphism in the Verhabilities method().

  • 2

    This does not answer the question that was asked. Moreover, the OP itself stated "In C# we can implement several Interfaces".

  • 2

    Yes, I set the top of the text to the goal of my post.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.