Do interfaces solve the “deadly diamond of death” issue?

心已入冬 提交于 2019-12-18 17:00:20

问题


Do interfaces solve the deadly diamond of death problem?

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.

Though interfaces are a good way for solving method ambiguity, I guess they fail in the case of variables?

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


回答1:


Java resists the multiple Concrete/abstract class inheritance but not multiple interface inheritance where you inherit abstract methods not implementation the better post with good explaination and examples http://www.tech-knowledgy.com/interfaces-sovles-diamond-death/




回答2:


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

It is possible for a class to inherit more than one field with the same name. Such a situation does not in itself cause a compile-time error. However, any attempt within the body of the class to refer to any such field by its simple name will result in a compile-time error, because such a reference is ambiguous.

A similar statement applies with respect to interfaces (JLS §9.3).

The sample code in the answer by Óscar López is excellent. Here's 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 because interfaces now can declare default methods that subinterfaces and implementing classes can inherit. Since a class can implement multiple interfaces, this can cause ambiguities because distinct default methods with the same signature could be inherited from multiple interfaces.1 Java deals with this using a priority scheme to specify which default method is actually inherited. It requires explicitly overriding inherited default methods when the priority scheme fails to yield a single winner.

Note that in no case does Java have a Diamond problem, which is a very specific subclass of problems that can come with multiple inheritance.2 The "Diamond" part refers to the shape of the class inheritance diagram that's required in order to have the problem. In C++, the Diamond problem can arise if a class A inherits from two classes B and C, each of which inherits from a common base class D. In that case, any public members of D ends up appearing twice in A—once inherited through B and once through C. Also, whenever an instance of A is constructed or destroyed, the constructor or destructor for D ends up being called twice (often with disastrous consequences, hence the "of death" part of the name). C++ solves these issues by providing virtual inheritance. (See the discussion here for details.)

1 Note the use of the word "distinct". There is no issue if the same default method is inherited through two parent interfaces that in turn extend a common base interface where the default method is defined; the default method is simply inherited.

2 Other multiple inheritance issues—like the ambiguities that can arise in Java with interface fields, static methods, and default methods—technically have nothing to do with the Diamond problem (actually, the Deadly Diamond of Death problem). However, much of the literature on the subject (and an earlier version of this answer) ends up lumping all multiple inheritance problems under the rubric "Diamond of Death." I guess the name is just too cool to be used only when technically appropriate.




回答3:


An interface can't have attributes. When you write this:

public interface Foo {
    int x;
}

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

public interface Foo {
    public static final int x;
}

Let's say you have another interface with a similarly named constant:

public interface Bar {
    int x;
}

And if you were to use the x value in a class that implements both Foo and Bar you'll have to qualify those constants, leaving no room for ambiguities, like this:

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

So no diamond in here. Anyway, declaring constants in an interface is frowned upon nowadays, most of the time you're better off using an enumeration for the same effect.




回答4:


No, you don't. Interfaces don't have any variables, other than static final ones.

If you actually write, compile, and execute those interfaces and classes you'll have your answer. That x variable is not a class member, so there's no ambiguity.

This is one of those questions that you can easily answer for yourself by writing the code and letting the JDK tell you. It'll be faster than asking here.




回答5:


Deadly Diamond Of Death Problem.

class A
{
void eat()
{

}
}

class B and C extend A and Override eat() method

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


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

now if we have multiple Inheritance what will Happen in following case.

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



回答6:


The Deadly Diamond of Death is a problem with variables, but an even bigger problem with virtual methods. If classes Moo1 and Moo2 were to both inherit from class Foo and override abstract virtual function Bar, and if a class Zoo were allowed to inherit from Moo1 and Moo2, without having to add its own override of Bar, it it would be unclear what method Bar of a Zoo should do. Interfaces avoid that issue by requiring that every class that implements an interface must supply its own implementation for all of the interface members, and by specifying that all members of an interface will be considered identical in all interfaces which extend it directly or indirectly. Thus, in the above situation, if Foo, etc. were interfaces rather than classes, then any class which implements Zoo would be required to implement Foo.Bar, which would be synonymous with Moo1.Bar, Moo2.Bar, and Zoo.Bar.



来源:https://stackoverflow.com/questions/9860811/do-interfaces-solve-the-deadly-diamond-of-death-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!