继承和接口

11

我一直在试图理解在接口涉及到继承时的继承关系。我想知道如果遵循以下方式,子类是如何创建的:

例如,假设我有:

  1. 一个实现接口I的超类
  2. 和几个扩展超类A的子类

我的问题

  1. 我是否必须在所有扩展A的子类中提供接口方法'q和r'的实现?

  2. 如果我没有在子类中提供接口的实现,那么我是否必须将该子类作为抽象类?

  3. 任何子类是否可能实现I?例如,C类扩展了A并实现了I,这是可能的吗?尽管它已经扩展了实现I的超类?

  4. 假设我没有提供接口I中方法r的实现,那么我将不得不将超类A变为抽象类!这是正确的吗?

我的示例代码:

    //superclass
    public class A implements I{
    x(){System.out.println("superclass x");}
    y(){System.out.println("superclass y");}
    q(){System.out.println("interface method q");}
    r(){System.out.println("interface method r");}
    }

    //Interface
    public Interface I{
    public void q();
    public void r();
    }

    //subclass 1
    public class B extends A{
    //will i have to implement the method q and r?
    x(){System.out.println("called method x in B");}
    y(){System.out.println("called method y in B");}
    }

    //subclass 2
    public class C extends A{
    //will i have to implement the method q and r?
    x(){System.out.println("called method x in C");}
    y(){System.out.println("called method y in C");}
}

类方法也需要有返回类型。 - Mordechai
4个回答

8

1) 不需要在子类中实现方法,因为它们已经在超类中定义过了。子类将继承这些方法的定义。

2) 不需要,在1中已经解释了。唯一的例外是如果超类是抽象的并且没有实现接口,那么如果子类不是抽象的,则需要在子类中实现它。

3) 不需要。虽然可能会编译成功,但是没有任何效果,所以不应该这样做。

4) 是的,这是正确的。如果您没有实现接口中的一个方法,则需要将类声明为抽象类。


谢谢你澄清了这个问题!我还有一个问题。假设A现在是一个抽象超类,并且仍然实现接口I,如果我仍然想使用A的方法(比如接口方法q()),那么这会对子类产生什么影响? - Jon Snow
抽象类仍然可以为方法提供实现,因此您可以通过子类正常使用它们。因此,如果您在A中定义了x(),但没有在B中定义,然后调用b.x()(其中b是类型B的对象),它将使用A中提供的方法定义,就像A不是抽象类一样。 - Jonathon Ashworth
谢谢!感谢所有回答的人 :) - Jon Snow
如果我想将一个子类强制转换为超类实现的接口,该怎么办?它会抛出ClassCastException异常。我该如何实现这个操作? - gyosida

1

只有抽象类才能保持它们的抽象性,这意味着抽象类不需要为接口中的方法提供实现。

由于 A 是具体的,它必须提供实现。然后,A 的子类将继承那些来自 A 的实现。

但是,如果 A 是抽象的并且没有为方法提供实现,则 BC 必须提供实现。


你能告诉我为什么在这种情况下我应该使用抽象类吗?设计方面有什么原因吗?为什么不直接为一个类使用接口,而是要在中间加入抽象层次结构呢? - johnny
MouseAdapter这样的类,是为什么你想在这种情况下引入抽象类的很好的例子。主要是因为如果接口有太多的方法,那么具体的实现大部分时间都不会感兴趣。但是如果你考虑像[Runnable]这样只有一个方法的接口,那么创建抽象类就没有意义了。 - Bhesh Gurung
此外,如果设计需要在类层次结构内重复使用一些代码,则抽象基类是最好的选择。 - Bhesh Gurung

1

1:不需要,在超类中实现它们,子类就不需要再实现了。

2:如果你在超类中没有实现这些方法,那么你需要将其定义为抽象方法,然后让具体的子类去实现这些方法。

3:是的,但是完全是多余的,因为你的超类已经实现了它们。

4:是的,当你扩展超类时,你应该在类中实现这些方法。


0

接口是对外界的承诺,即“我可以提供这些方法。”

1)和2)和4)由于超类A已经实现了接口I,它已经向外界做出了承诺。超类A可以通过以下方式履行该承诺:

  • 实现该方法-在这种情况下,您的子类已经继承了该方法,不需要实现任何内容。
  • 声明自己为抽象-在这种情况下,您的子类必须实现抽象方法,或者也可以将自己声明为抽象,并将“包袱”传递给扩展子类的任何类。

3)超类A的所有子类已经实现了I,因为它们继承了“承诺”,所以Class C extends A implements I是多余的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接