要实现多重继承,我们必须使用接口,但为什么接口方法没有实体,为什么必须在派生类中重写它们?
我真的想要一个清晰的答案,不涉及太多的电脑术语,我似乎无法理解这一点,我已经提到了各种参考文献
答案 0 :(得分:13)
因为Java与C ++或Eiffel之类的语言相比,只有类型的多重继承(即接口和一个类),而不是 state 的多重继承和行为。后者增加了巨大的复杂性(尤其是国家)。
Java设计人员(和C#,就此而言)选择不包括它,因为它给C ++程序员带来了非常难以调试的问题。您可以通过实现多个接口来解决需要真正多重继承的大多数问题,因此权衡被认为是值得的。
请注意,行为(非状态)的多重继承可能会以虚拟扩展方法的形式出现在Java 8中(除非它们像其他许多东西一样推迟它) em>其中一个接口可以声明一个委托给另一个类中的一个的方法,然后该类存在于实现该接口的所有类型上。
答案 1 :(得分:2)
接口声明实现类提供的WHAT服务,而不是HOW(这是实现类的工作)。多重继承被认为是不好的,因为它会导致复杂的代码和类层次结构。
答案 2 :(得分:2)
接口只有常量变量(public + static + final)和抽象方法(public和amp; abstract)。这些应该由实现接口的类使用。
接口简单地说'Am a contract',如果你想使用它,应该坚持一些规则(给所有抽象方法实现)。
Java中省略了多重继承,确保一个类只能扩展一个类,以避免diamond problem。无论如何,您可以通过使用接口在Java中进行多种类型的继承。
答案 3 :(得分:1)
Java接口包含必须由实现接口的类实现的方法列表。因此,这些方法没有正文:每个方法的主体都在实现类中。
答案 4 :(得分:1)
简单回答:
接口提供了实施标准。
<强>解释强>
在Java中,接口类似于抽象类,因为其成员未实现。例如,
public interface Comparable
{ boolean less(Object m);
boolean greater(Object m);
boolean lessEqual(Object m);
boolean greaterEqual(Object m);
}
界面提供了实施标准 使用接口的好处是它们模拟多重继承。 Java中的所有类都必须具有一个基类,唯一的例外是
java.lang.Object
(Java类型系统的根类); java中不允许多继承类。
所有实例方法都隐含public
和abstract
。您可以将它们标记为这样,但不鼓励这样做,因为标记被认为是过时的练习。接口本身不需要是公共的,标准库中的几个接口不是公共的,因此只能在内部使用。
接口创建类可以实现的协议。请注意,可以扩展接口(以获取新接口),就像扩展类一样。实际上可以扩展几个接口。 接口 因此享有多重继承的好处。 ( Classes 没有。)接口的多重继承几乎没有缺点(小名称冲突问题是一个例外)。与C++
中的实现的多重继承有大缺点。这些包括效率注意事项以及确定在某些情况下将执行哪些代码的语义难度。
实现 Comparable 的多项式类需要实现接口中声明的所有函数。
public class Polynomial implements Comparable
{ . . .
boolean less(Object m){ . . . }
boolean greater(Object m){ . . . }
boolean lessEqual(Object m){ . . . }
boolean greaterEqual(Object m){ . . . }
Polynomial multiply(Polynomial P){ . . . }
. . .
}
类可以选择实现任意数量的接口。实现接口的类必须为接口的所有方法提供主体。此外,我们希望抽象类可以选择实现接口的一部分,其余部分留给非抽象子类。
接口的用处不仅仅是为其他程序员发布协议。任何函数都可以具有 interface 类型的参数。 实现接口的类中的任何对象都可以作为参数传递。
<强>参考文献:强>
Interface
Interfaces
Interface Wiki
答案 5 :(得分:0)
接口方法没有正文 喜欢
public interface Flyable
{
public void fly();
}
因为界面本身不会做任何事情
接口定义合同。
另一方面,界面定义了一个类可以做什么, 不是它是什么。所以界面通常是动词。
所以Flyable界面什么也没做,只是定义了植入的合同 FlyableObjects将会飞行。
像:
class Rocket implements Flyable
{
public void fly()
{
// do the stuffs.
}
}
当然,我们也只能通过接口实现多重继承。
答案 6 :(得分:0)
如果界面有尸体那么它就会带回致命的死亡钻石问题。
请考虑此示例具有与主体的接口
interface A {
void print(){ System.out.print("A") }
}
interface B {
void print(){ System.out.print("B") }
}
interface C extends A, B {
// now since A and B have bodies interfaces would have had choice to not to override the default behavior
}
public class C_Implementer implements C{
public static void main(String args[]){
C c = new C_Implementer();
c.print(); // gotcha!!!!! what should it print, A or B????
}
}
答案 7 :(得分:0)
您在问&#34;为什么Java不支持多重继承实施?&#34;
这在Java教程Multiple Inheritance of State, Implementation, and Type中讨论过,但我想提供一个实现多重继承问题的具体示例(以及最后的新语言特性解决方案)。
想象一下两个接口(在我们提出的允许接口方法体的Java版本中)定义了一个具有相同名称的方法。
public interface FaceOne {
public void method() {
System.out.println("FaceOne Version");
}
}
public interface FaceTwo {
public void method() {
System.out.println("FaceTwo Version");
}
}
一个类实现两个接口,但不会覆盖该方法。
public class Inheriter implements FaceOne, FaceTwo {
}
当我调用Inheriter.method()
时,由于该类从其祖先继承了该方法,因此问题出现了:输出打印&#34; FaceOne版本&#34;或&#34; FaceTwo版本&#34;?
此外,如果该类要覆盖该方法,但又希望使用super
调用其祖先的版本,则编译器将无法在该方法的某个版本之间进行选择。
这就是Java不支持多重继承实现的原因。
顺便说一下,我认为在语言中实现这一点的一种优雅方式如下:
继续强制实现类来覆盖其祖先接口的方法。这解决了非重写方法的第一个问题。
然后,使用与that of accessing an enclosing instance for an inner class类似的表示法来访问具有super
的特定祖先界面。然后,Inheriter类将有多个选项:
请勿致电super.method()
,而应仅使用新定义的实施方式。
使用FaceOne.super.method()
制作默认的继承实现输出&#34; FaceOne版本&#34;。
使用FaceTwo.super.method()
制作默认的继承实现输出&#34; FaceTwo Version&#34;。
使用以上组合:
一个实现可能是:
@Override
public void method() {
FaceOne.super.method();
FaceTwo.super.method();
System.out.println("Inheriter Version");
}
对外输出:
FaceOne版
FaceTwo Version
继承人版本
编辑:根据this question,这显然是Java 8中默认实现的结构。