Can interfaces solve the “deadly diamond of death" problem?

Do interfaces solve the deadly diamond of death ?

I don’t think so, for example:

// A class implementing two interfaces Interface1 and Interface2. // Interface1 has int x=10 and Interface2 has int x = 20 public class MultipleInterface implements Interface1, Interface2{ public void getX(){ System.out.println(x); } } 

Here we get an ambiguous x .

Although interfaces are a good way to resolve a method's ambiguity, I think they fail in the case of variables?

Am I right? If I am missing something, enlighten me.

+4
source share
6 answers

Java resists the multiple inheritance of the Concrete / abstract class, but does not inherit the inheritance of multiple interfaces where you inherit abstract methods, rather than implementing a better post with a good explanation and examples http://www.tech-knowledgy.com/interfaces-sovles-diamond- death /

+3
source

When a class inherits two variables from its parent interfaces, Java insists that any use of the variable name in question be fully qualified. This solves the problem. See Java Language Specification in Section 8.3 :

A class can inherit more than one field with the same name. This situation alone does not cause compile-time errors. However, any attempt within the body of a class to refer to any such field by its simple name will lead to a compile-time error, since such a link is ambiguous.

A similar instruction applies to interfaces ( JLS §9.3 ).

The sample code in Óscar López's answer is excellent. Here is another example:

 class Base { int x = 10; } interface Interface { int x = 20; } class SingleInheritance implements Interface { int y = 2 * x; // ok } class MultipleInheritance extends Base implements Interface { int y = 2 * x; // compile-time error int z = 2 * Interface.x; // ok } void aMethod(MultipleInheritance arg) { System.out.println("arg.x = " + arg.x); // compile-time error System.out.println("x = " + Interface.x); // ok } 

Edit

Java 8 introduces a limited form of multiple inheritance for methods, as interfaces can now declare default methods that can inherit subinterfaces and implementing classes. Since a class can implement several interfaces, this can cause ambiguity, because different default methods with the same signature can be inherited from several interfaces. 1 Java deals with this using a priority scheme to indicate which default method is actually inherited. It requires explicitly overriding inherited methods by default when the priority scheme does not give a single winner.

Note that in no case does Java have a problem with Diamond, which is a very specific subclass of problems that can have multiple inheritance. 2 The “Diamond” part refers to the form of the class inheritance diagram needed to solve this problem. In C ++, the Diamond problem can occur if class A inherits from two classes B and C, each of which inherits from a common base class D. In this case, any public members of D end up appearing twice in - B and once through C. Besides In addition, whenever an instance of A is built or destroyed, the constructor or destructor for D ends up being called twice (often with catastrophic consequences, hence part of the death of “death”). C ++ solves these problems by providing virtual inheritance. (For more details see the discussion here )

1 Note the use of the word "miscellaneous". There is no problem if the same method is inherited by default through two parent interfaces, which, in turn, extend the common base interface, where the default method is defined; the default method is simply inherited.

2 Other multiple inheritance problems & mdash, such as ambiguities that can occur in Java with interface fields, static methods, and standard methods, technically have nothing to do with the Diamond problem (in fact, the problem of the death diamond). However, most of the literature on this subject (and an earlier version of this answer) ends up with the fact that all the problems of multiple inheritance fall under the heading "Diamond of Death". I think this is just too cool to be used only when it is technically feasible.

+12
source

An interface cannot have attributes. When you write this:

 public interface Foo { int x; } 

Under the hood, it implicitly converts to a constant, something like this:

 public interface Foo { public static final int x; } 

Let's say you have another interface with the same constant:

 public interface Bar { int x; } 

And if you must use the value of x in a class that implements both Foo and Bar , you will have to qualify these constants without leaving room for ambiguities, for example:

 public class Baz implements Foo, Bar { private int y = Foo.x + Bar.x; } 

So there is no diamond. In any case, declaring constants in an interface is currently frowned upon; in most cases, you'd better use an enumeration for the same effect.

+11
source

No no. Interfaces have no variables other than static final ones.

If you really write, compile and execute these interfaces and classes, you will have your own answer. This variable x not a member of the class, so there is no ambiguity.

This is one of those questions that you can easily answer yourself by writing code and telling the JDK. It will be faster than asking here.

+5
source

Deadly diamond is the problem of death.

 class A { void eat() { } } 

class B and C extend A and override the eat () method

 class B extends A { void eat() { } } class C extends A { void eat() { } } 

now, if we have multiple Inheritance, what will happen in the following case.

  class D extends B ,C { //which eat() method will be inherited here for class D ? a problem ? ? } 
0
source

The Deadly Diamond of Death is a problem with variables, but an even bigger problem with virtual methods. If the classes Moo1 and Moo2 were to inherit from the class Foo and override the abstract virtual function Bar , and if the class Zoo was allowed to inherit from Moo1 and Moo2 , without adding its own override Bar , it would not be clear what the Bar method should do for Zoo . Interfaces avoid this problem by requiring that each class that implements the interface must provide its own implementation for all members of the interface and stating that all members of the interface will be considered identical in all interfaces that distribute it directly or indirectly . So in the above situation, if Foo , etc. They were interfaces, not classes, then to implement Foo.Bar , you would need any class that implements Zoo , which would be synonymous with Moo1.Bar , Moo2.Bar , and Zoo.Bar .

0
source

Source: https://habr.com/ru/post/1403319/


All Articles