Perché riduci l'ereditarietà multipla al problema del diamante?

2

Ogni volta che leggo qualcosa come questo :

Many programmers exhibit a slight, involuntary shudder whenever multiple inheritance is mentioned. Ask them to identify the source of their unease and they will almost certainly finger the so-called Deadly Diamond of Death inheritance pattern. In this pattern, classes B and C both inherit from class A, while class D inherits from both B and C. If B and C both override some method from A, there is uncertainty as to which implementation D should inherit.

Nonpossotornareindietroenonchiedere:perchériduciilproblemadell'ereditarietàalproblemaDiamond?Capiscicheilproblemaèilnomeconflittochederivadallaconvergenzadelleclassi,piuttostochedallalororiconversione(diamante)?NonhaibisognodellaradicecomuneUnaclasse/interfacciaperilconflittodidenominazione,comemostraildiagramma

È MI che abilita la convergenza di classe e, quindi, i conflitti di denominazione, che sono il problema di cui stiamo parlando. Perché ti piace come non è il caso e continua a chiamarlo un problema di diamante piuttosto che un problema di MI?

    
posta Valentin Tihomirov 20.11.2015 - 09:03
fonte

1 risposta

7

Hai parzialmente ragione: il problema esiste anche nel caso dell'ereditarietà multipla, ma può essere facilmente risolto in alcune lingue; il diamante, d'altra parte, non può essere risolto facilmente.

In C #, l'ereditarietà multipla è vietata, ma una classe può implementare più interfacce. Immagina che la classe Example implementa IModifiable e ITransformable . Queste due interfacce hanno sia un metodo Transform(string) : string . Come implementeresti questo?

public class Example
{
    public string IModifiable.Transform(string value);
    public string ITransformable.Transform(string value);
}

Questo significa che non c'è ambiguità. Non hai uno, ma due metodi con firme chiaramente distinte.

Ora, immagina il caso diamante:

public abstract class Parent
{
    public abstract void DoSomething(string value);
}

public class Child1 : Parent
{
    public override void DoSomething(string value)
    {
        // Do something here.
    }
}

public class Child2 : Parent
{
    public override void DoSomething(string value)
    {
        // Do a completely different thing.
    }
}

public class Example : Child1, Child2
{
}

Ora, quando chiamiamo il metodo DoSomething su Example , in realtà vogliamo richiamare il metodo dichiarato in Parent . Quindi, come deciderà il runtime quale delle implementazioni eseguire?

    
risposta data 20.11.2015 - 10:10
fonte

Leggi altre domande sui tag