【问题标题】:Why can a class implement multiple interfaces but not inherit multiple classes? [closed]为什么一个类可以实现多个接口却不能继承多个类? [关闭]
【发布时间】:2017-07-02 05:20:55
【问题描述】:

我找到的答案之一是“如果属于两个不同类的两个方法/变量具有相同的名称,多重继承会导致冲突”。但我认为在实现多个接口时也可能存在冲突。例如,考虑一个实现两个具有相同变量名的接口的类(变量可以在接口中定义,默认情况下它们是最终的)在它们内部声明

interface Ainterface {

    public final static int i=10;

}


class InterfaceCheck implements Ainterface {
        public static void main(String[] args) {        
        System.out.println(i);
    }

}

上面的代码运行良好

interface Ainterface {

    public final static int i=10;

}

interface Binterface {

    public static final int i=20;

}

class InterfaceCheck implements Ainterface,Binterface {
        public static void main(String[] args) {        
        System.out.println(i);
    }

}

根据互联网上的消息来源“实现多个接口永远不会导致冲突” 但是上面的代码会产生错误。所以这就是我所说的冲突。

【问题讨论】:

  • 当同一个基类通过不同的继承链被多次继承时,事情变得复杂了。这是 Java 的设计者不想涉及的事情。因此限制只继承一个类。最有趣的多重继承应用可以从接口中获得。
  • @chirag 正如我在发布的答案中提到的,定义的方法或字段将显示冲突。由于字段是静态的,您可以在 println() 中安全地使用 Ainterface.i 或 Binterface.i。如果它是函数式接口的默认方法,它会在多重继承接口时显示编译错误,并且不允许两个接口被多重继承。
  • @ChiragJain 很高兴你分析了所有细节,我记得当我阅读 Khalid 的 java 时我也是这么想的。即使在这里,如果您在不使用 InterfaceName.i 的情况下访问公共字段,也会出现编译错误!如果您不访问模棱两可的字段,那么您在编译和运行时都很好。如果您喜欢 ans,请点赞。使用 Outer-Inner 类时也会出现同样的问题。
  • 是的,这个示例错误,正如您所料。确实有冲突。但毫无疑问。你有什么问题?
  • @Nitish 由于声誉低,我无法投票。

标签: java inheritance interface


【解决方案1】:

变量可以在接口中定义,默认为final

*Java 接口中的变量默认为 publicstaticfinal。这是因为接口并不意味着规定实现,只是行为。这意味着接口中的变量实际上是常量。

静态变量不会被继承。所以不存在冲突的可能。

【讨论】:

  • 我没有看到问题。您发布的带有 2 个接口的代码无法编译。所以不可能有你所说的冲突。
  • 在多重继承中也可能引发同样的错误。为什么他们当时不允许多重继承?无论如何,我得到了答案。谢谢
  • 如果我们能以这种方式结束讨论,一切都会变得如此简单。至少不要关闭这个问题。如果有人有答案怎么办?我的问题不再不清楚,因为您已标记
【解决方案2】:

它将实现来自两个接口的对象。因此,如果两个接口都具有相同的变量,它将作为单个变量实现。这同样适用于方法。

【讨论】:

    【解决方案3】:

    由于菱形问题,不允许在类中进行多重继承。简单的答案是 super.commonMethodInBothClasses() 将如何工作? jvm如何知道在super.method调用的子类中使用哪个方法定义?这会导致歧义。在 java8 中,你可能会发现一个惊喜,我们可以在接口中定义方法,称为默认方法。但是在接口(功能接口)中仍然允许多重继承,但是这里在编译时检查,如果接口中有定义,则接口必须没有共同的方法。如果声明了两个方法但没有定义相同的签名,则允许冲突,因为两个接口中都不存在的定义之间存在冲突。

    Interface1{
      public static final int a= 10;
    default void method1(){
    // definition
    }
    void method2DeclaredOnly();
    }
    
    Interface2{
     public static final int a = 20;
    default void method3(){
    // definition
    }
    void method2DeclaredOnly();
    }
    
    class MyClass implements Interface2, Interface1{
    
    void method2DeclaredOnly(){
    System.out.println(Interface1.a); // static members can be referred. directly. Classname.field 
    // defined here allowed.
    }
    

    但是,必须定义默认方法,如果你要实现这两个接口,否则它会如前所述给出编译错误。现在这里棘手的部分是,常见的默认方法是使用调用的 IA.超级.abc();

        interface IA{
            default void abc(){
                //..
            }
        }
    
        interface IB{
    default void abc(){
                //..
            }
        }
    
        class A implements IA, IB
        {
            public void abc(){
                IA.super.abc(); //..
    
                    }
        }
    

    【讨论】:

      猜你喜欢
      • 2013-05-24
      • 2012-06-17
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      • 2021-09-12
      • 1970-01-01
      • 2013-09-22
      相关资源
      最近更新 更多