Why does C # not allow multiple inheritance?

18

In C # we can implement several interfaces. But why can not we inherit from more than one base class?

    
asked by anonymous 31.01.2014 / 18:58

3 answers

22
Inheriting many concrete classes is a major source of problems from the point of view of designing a programming language: what 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 the diamond inheritance . Consider the following inheritance pattern:

  A
 / \
B   C
 \ /
  D

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

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

What version of the method is called? Is the version defined in B or a defined in C?

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

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 multiply from purely abstract classes.

    
31.01.2014 / 19:07
6

Basically because this would make inter-operability between languages via the Common Language Runtime (CLR) impossible, since different languages define multiple inheritance in subtly different ways.

In relation to the diamond problem, referred to by the phrase, several languages have decided to include multiple inheritance, and there are several solutions to the diamond problem. C ++ requires an explicit resolution of the foo method in the D class. Scala has traits , and solves the diamond problem in the traits declaration order:
  • 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 feels that in 99% of cases, multiple inheritance is not really necessary (personally, I agree). The principle of "composition over inheritance" is perhaps one of the most important software design principles that all software engineers must know - it will save your life many times over. during your career.

That said, there are projects that tried to create the traits concept in C #, such as NRoles through a post-compiler , or Inherit .

Source: Why does not C # support multiple inheritance? / Traits: How Scala Tames Multiple Inheritance

    
31.01.2014 / 19:03
4

As the question has already been answered, here is 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 Triathlete knows how to run, cycle and swim, we would like him 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 abilities to demonstrate the polymorphism.

Follow 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 the skills of each athlete.

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. While being in a competition that requires only one skill, all abilities of the triathlete are shown by polymorphism in the method Skills ().

    
31.01.2014 / 19:16