4

Whenever I read something like this:

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.

enter image description here

I cannot come back and not to ask: why do you reduce multiple inheritance problem to the Diamond problem? Do you understand that problem is the name conflict that stems from convergence of classes, rather than their reconvergence (diamond)? You do not need the common root A class/interface for the naming conflict to happen, as the diagram shows

enter image description here

It is MI which enables the class convergence and, thus, naming conflicts, which are the problem we are talking about. Why do you pff like it is not the case and keep calling it a diamond problem rather than MI problem?

  • Many programmers exhibit a slight, involuntary shudder whenever inheritance, *of any sort*, is mentioned. Don't use inheritance and all such problems, including the diamond problem, go away. – David Arno Nov 20 '15 at 09:33
  • 1
    @DavidArno: ...and plenty of other problems appear in its place, the problems that were solved by the invention of inheritance. It exists for a good reason, you know. – Mason Wheeler Nov 20 '15 at 11:24
  • 3
    The naming conflicts can be resolved by using Class::Method references in the programming language when ever the compiler determines that the reference cannot be uniquely determined. However, Diamond inheritance of the same class is not so easy to solve. – Michael Shaw Nov 20 '15 at 11:33
  • @MasonWheeler, Language features that appear a good idea at the time can later be found to be a bad idea. Inheritance is one such example of this; `goto` is another. – David Arno Nov 20 '15 at 13:09
  • 1
    @DavidArno: Sorry, but that's a ridiculous and completely wrong idea. After Dijkstra not only declared `goto` to be "considered harmful" but *proved that it could be trivially replaced with structured-programming constructs in every case*, its use was phased out in high-level languages and today it's barely used anywhere by anyone for anything. But this doesn't compare with inheritance in any way. – Mason Wheeler Nov 20 '15 at 13:23
  • 1
    I still think goto is a reasonable solution when you have complex patterns of breaks on nested loops. Even if you can solve this with deep returns in functions and recursion. You can get fast + simple code with goto in this case, as always, with prudence. – RomuloPBenedetti Feb 16 '20 at 07:14

1 Answers1

9

You're partially right: the problem exists in the case of the multiple inheritance too, but can easily be solved in some languages; diamond, on the other hand, cannot be solved that easily.

In C#, multiple inheritance is forbidden, but a class can implement multiple interfaces. Imagine that the class Example implements IModifiable and ITransformable. Those two interfaces have both a method Transform(string) : string. How would you implement this?

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

This means there is no ambiguity. You have not one, but two methods with clearly distinct signatures.

Now, imagine the diamond case:

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
{
}

Now, when we call the method DoSomething on Example, we actually want to invoke the method declared in Parent. So how would the runtime decide which one of the implementations to run?

Arseni Mourzenko
  • 134,780
  • 31
  • 343
  • 513
  • 1
    Of course, diamond ambiguity is also a solved problem, though not all languages bother to implement a solution. The CLOS is one that does by using the order in which superclasses are declared. In this case, calling `DoSomething` on `Example` would use `Child1`'s implementation. – 8bittree Nov 20 '15 at 15:31