abs*_*son 145 java oop inheritance language-design interface
Java不允许多重继承,但它允许实现多个接口.为什么?
Boz*_*zho 216
因为接口只指定什么类是做,而不是如何它是做什么的.
多继承的问题是两个类可能定义了做同样事情的不同方式,而子类无法选择要选择的方法.
Syn*_*tic 90
我的一位大学教师用这种方式向我解释:
假设我有一个类,一个是Toaster,另一个类是NuclearBomb.它们都可能具有"黑暗"设置.它们都有一个on()方法.(一个有一个off(),另一个没有.)如果我想创建一个类,这是这两个的子类...正如你所看到的,这是一个问题,可能真的在我脸上爆炸了.
因此,主要问题之一是,如果您有两个父类,它们可能具有相同功能的不同实现 - 或者可能具有两个具有相同名称的不同功能,如我的教师示例中所示.然后你必须处理决定你的子类将使用哪一个.有一些方法可以解决这个问题 - 当然C++会这样做 - 但Java的设计者认为这会让事情变得太复杂.
但是,通过接口,您将描述类能够执行的操作,而不是借用另一个类的执行方法.与多个父类相比,多个接口不太可能导致需要解决的棘手冲突.
Mic*_*rdt 22
因为继承被过度使用,即使你不能说"嘿,那个方法看起来很有用,我也会扩展那个类".
public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter,
AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...
Run Code Online (Sandbox Code Playgroud)
Pra*_*ava 15
这个问题的答案在于Java编译器(构造函数链接)的内部工作。 如果我们看到Java编译器的内部工作原理:
public class Bank {
public void printBankBalance(){
System.out.println("10k");
}
}
class SBI extends Bank{
public void printBankBalance(){
System.out.println("20k");
}
}
Run Code Online (Sandbox Code Playgroud)
编译后看起来像这样:
public class Bank {
public Bank(){
super();
}
public void printBankBalance(){
System.out.println("10k");
}
}
class SBI extends Bank {
SBI(){
super();
}
public void printBankBalance(){
System.out.println("20k");
}
}
Run Code Online (Sandbox Code Playgroud)
当我们扩展类并创建其对象时,一个构造函数链将运行到Object类。
上面的代码可以正常运行。但是,如果我们有另一个Car扩展的类Bank和一个混合(多重继承)类,则SBICar:
class Car extends Bank {
Car() {
super();
}
public void run(){
System.out.println("99Km/h");
}
}
class SBICar extends Bank, Car {
SBICar() {
super(); //NOTE: compile time ambiguity.
}
public void run() {
System.out.println("99Km/h");
}
public void printBankBalance(){
System.out.println("20k");
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,(SBICar)将无法创建构造函数链(编译时歧义)。
对于接口,这是允许的,因为我们无法创建它的对象。
对于新的概念default和static方法,请参考interface中的default。
希望这能解决您的查询。谢谢。
您可以在有关多重继承的oracle 文档页面中找到此查询的准确答案
状态的多重继承: 能够从多个类继承字段
Java 编程语言不允许您扩展多个类的原因之一是为了避免状态的多重继承问题,即从多个类继承字段的能力
如果允许多重继承并且当您通过实例化该类来创建对象时,该对象将从该类的所有超类中继承字段。它会导致两个问题。
实现的多重继承:能够从多个类继承方法定义
这种方法的问题:名称冲突和歧义。如果子类和超类包含相同的方法名称(和签名),编译器无法确定要调用哪个版本。
但是java支持这种带有默认方法的多重继承,这是自 Java 8 发布以来引入的。Java 编译器提供了一些规则来确定特定类使用的默认方法。
有关解决钻石问题的更多详细信息,请参阅以下 SE 帖子:
类型的多重继承: 一个类可以实现多个接口的能力。
由于接口不包含可变字段,因此您不必担心此处状态的多重继承导致的问题。
小智 7
Java不支持多重继承有两个原因:
Object类的子类。当子类继承了多个超类时,子类就获得了Object类的属性的歧义性。super()超级类构造函数。如果一个类有多个超类,它就会变得混乱。因此,当一个类从多个超类扩展时,我们会得到编译时错误。
Java 仅支持通过接口进行多重继承。一个类可以实现任意数量的接口,但只能扩展一个类。
不支持多重继承,因为它会导致致命的菱形问题。然而,它是可以解决的,但它会导致系统复杂,因此 Java 创始人放弃了多重继承。
在 James Gosling 于 1995 年 2 月(链接 - 第 2 页)题为“Java:概述”的白皮书中,给出了 Java 不支持多重继承的想法。
根据高斯林的说法:
“JAVA 忽略了 C++ 中许多很少使用、理解不足、令人困惑的特性,根据我们的经验,这些特性带来的弊大于利。这主要包括运算符重载(尽管它确实有方法重载)、多重继承和广泛的自动强制转换。”
小智 5
据说对象状态是根据其中的字段来引用的,如果继承了太多的类,它就会变得不明确。链接在这里
http://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html