【问题标题】:In Java, what really happens when an interface "extends" another interface?在 Java 中,当一个接口“扩展”另一个接口时会发生什么?
【发布时间】:2014-08-25 10:41:29
【问题描述】:

我是 Java 编程新手,现在我正在尝试理解 OOP 概念(继承、多态等)。

我知道,当子类扩展超类(抽象与否)时,子类构造函数首先调用该超类的构造函数(super())。

我的问题是:

1) 接口的情况是否相同?我看过一些文章说接口没有构造函数,那么它们究竟是如何扩展的?

2) 为什么 Java 不支持多重继承,但一个接口可以“扩展”多个其他接口?

提前致谢。

【问题讨论】:

  • 我一直认为接口是一种契约,因为它基本上规定了实现类必须遵守的内容。因此,当一个合同扩展另一个合同时,它会获取源合同中包含的所有规则、规定和边界并添加自己的。
  • 接口是没有实现的契约(Java8 引入了默认方法)。通过扩展,您可以使用要由具体类实现的新“名称”来扩展合同。
  • 这个问题stackoverflow.com/q/8531292/1055241也可以帮助你理解接口的概念

标签: java oop inheritance interface constructor


【解决方案1】:

1) 接口的情况是否相同?我读过一些文章说接口没有构造函数,那么它们究竟是如何扩展的?

是的,接口中没有构造函数,您必须定义一个具体的类(实现该接口)来创建该接口类型的对象。

示例:您可以使用javap java.io.Serializable 查看java.io.Serializable 的个人资料,即:

public interface java.io.Serializable {
}

表示没有构造函数。

2) 为什么 Java 不支持多重继承,但一个接口可以“扩展”多个其他接口?

是的,您可以扩展多个接口,这是因为如果两个接口包含具有相同签名的 abstract 方法,编译器不会产生歧义。但是类的情况并非如此,如果您尝试扩展两个具有相同签名的方法的类,那么编译器将产生歧义,因为在不同的类中调用哪个方法作为方法声明可能会有所不同。

【讨论】:

  • 具体类会实现接口,不会扩展接口。我已经在你的答案中编辑了
  • 谢谢@GPRathour 我搞砸了扩展和实现会打字。
【解决方案2】:

是的,你可以做到。一个接口可以扩展多个接口。

interface Maininterface extends inter1, inter2, inter3{  
  // methods
}

不仅是接口,单个类也可以实现多个接口。那么显然会产生一个疑问,如果两个方法具有相同的方法名称怎么办。

有一个棘手的地方:

interface A
{
    void test();
}

interface B 
{
    void test();
}

class C implements A, B
{

    @Override
    public void test() {

    }     

}

然后单一实现适用于两者:)

【讨论】:

    【解决方案3】:

    1) 接口的情况是否相同?

    不是真的。接口的构造函数实际上没有意义,因为构造函数定义了一些初始状态,但接口没有状态。所以构造函数不会被调用。

    我读过一些文章说接口没有构造函数,那么它们究竟是如何扩展的?

    您应该将扩展接口视为对类型的更多扩展——也就是说,扩展某物的已定义行为。这就像签订合同并在末尾添加一些条款 - 你说“除了超级接口中定义的方法,我希望实现这个接口的类 实施______"

    扩展一个类有点类似,因为你也扩展了一个类型,但问题是扩展一个类应该被认为是向一个类型添加额外的状态/实现。因此,应调用超类构造函数以确保与超类定义相关的所有状态都已正确初始化。

    2) 为什么 Java 不支持多重继承,但一个接口可以“扩展”多个其他接口?

    您必须在这里小心,因为不只是一种多重继承。 Java确实支持类型的多重继承,这就是为什么你可以实现多个定义类型的接口。 Java 不支持的是 state 的多重继承(直到 Java 8 才允许实现的多重继承。请参阅下面的注释)。这就是你只能扩展 1 个类的原因——因为类定义了状态。

    因此,因为您可以继承多种类型,所以对于给定的接口扩展多个接口是完全可以的。这就像拿一份合同并在其背面装订其他几份合同。只要实现类遵循整个事情,你的程序就应该编译。

    注意:从 Java 8 开始,您现在可以通过接口中的 default 方法继承多个实现。在发生冲突的情况下,程序员必须显式地实现相关方法。

    【讨论】:

      【解决方案4】:

      首先尝试明确inheritance的概念。继承背后的基本概念是继承(获取)父类的所有属性(变量和方法)(考虑访问修饰符),并在子类中重写它们。

      假设我们有一个Class A

      class A{
        public void doA()
        {
        }
      }
      

      现在如果class B extends A(标记extends的字面意思)它将获得方法doA(),固有地。如果你看文字部分,实际上B extends A 似乎BA 的扩展版本。

      现在进入界面部分。如果我有接口InA

      interface InA{
        doInA();
       } 
      

      我尝试在class B 中继承它,我需要implement(再次标记文字)它。所以我会得到方法doInA()B 但我需要给它一个身体。

      如果是Interface to Interface,现在您已经使用了两个关键字进行继承。如果我问你interface InB 将继承interface InA,你会在extendsimplements 中选择什么关键工作? extends 听起来不是更合乎逻辑吗?因为InB 什么都没有实现,它只是变得更大,它将是InA 的扩展版本。

      现在让我们回答你两个关键问题:

      1.Is it the same case for Interfaces?

      Yes 和 No. 实际上只有在调用 child 的构造函数时才会调用 parent 的构造函数。因此,由于您永远无法调用子接口的构造函数,因此永远不会调用父接口的构造函数。它不调用父构造函数,但仍然保留构造函数调用的技术。

      2) How come multiple inheritance is not supported in Java but an interface can "extend" multiple other interfaces?

      看看这个Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?

      【讨论】:

        猜你喜欢
        • 2010-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-16
        • 1970-01-01
        • 2018-12-01
        • 1970-01-01
        • 2013-11-02
        相关资源
        最近更新 更多