为什么在Java中没有多重inheritance,但是允许实现多个接口?
Java不允许多重inheritance,但它允许实现多个接口。 为什么?
因为接口只指定类正在做什么,而不是如何做。
多重inheritance的问题是两个类可能定义了不同的方法来做同样的事情,子类不能select哪一个。
我的一位大学教师向我这样解释:
假设我有一个类,这是一个烤面包机,而另一个类是NuclearBomb。 他们都可能有一个“黑暗”的设置。 他们都有一个on()方法。 (一个有off(),另一个不)。如果我想创build一个类,这两个类的子类…你可以看到,这是一个问题,可能真的炸毁我的脸。
所以其中一个主要问题是,如果你有两个父类,它们可能会有不同的相同function的实现,或者可能有两个具有相同名称的不同function,就像我的教师的例子。 那么你必须处理决定你的子类将使用哪一个。 有一些方法可以处理这个问题,当然 – C ++是这么做的 – 但是Java的devise者觉得这会让事情变得复杂。
然而,有了一个接口,你正在描述这个类能够做什么,而不是借用另一个类的方法来做某件事。 与多个父类相比,多个接口不太可能导致需要解决的棘手冲突。
因为inheritance过度使用,即使你不能说“嗨,这个方法看起来有用,我也会扩展这个类”。
public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter, AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...
实现多个接口是非常有用的,不会给语言实现者和程序员带来太多问题。 所以这是允许的。 同时多重inheritance也很有用,会给用户造成严重的问题(可怕的钻石死亡 )。 而多数inheritance的事情也可以通过组合或使用内部类来完成。 因此,带来更多问题而不是获得多重inheritance是被禁止的。
出于同样的原因C#不允许多重inheritance,但允许您实现多个接口。
从C ++学到的经验教训是,它带来的问题比值得的更多。
接口是你的类必须实现的东西的契约。 您不能从界面获得任何function。 inheritance允许你inheritance父类的function(并且在多重inheritance中,这可能变得非常混乱)。
允许多个接口允许您使用devise模式(如Adapter)来解决使用多重inheritance可以解决的相同types的问题,但是采用更可靠和可预测的方式。
据说对象状态是关于其中的字段来引用的,如果inheritance的类太多,就会变得模糊不清。 链接在这里
http://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html
由于这个话题不是很接近我会发布这个答案,我希望这可以帮助别人理解为什么java不允许多重inheritance。
考虑以下课程:
public class Abc{ public void doSomething(){ } }
在这种情况下,Abc类不会扩展什么权利? 没有那么快,这个类隐式扩展了Object类,这个基类允许在java中工作。 一切都是一个对象。
如果您尝试使用上面的类,则会看到您的IDE允许使用像equals(Object o)
, toString()
等方法,但是您没有声明这些方法,它们来自基类Object
你可以尝试:
public class Abc extends String{ public void doSomething(){ } }
这很好,因为你的类不会隐含extends Object
但会扩展String
因为你说了。 考虑以下更改:
public class Abc{ public void doSomething(){ } @Override public String toString(){ return "hello"; } }
如果你调用toString(),你的类将总是返回“hello”。
现在想象下面的课:
public class Flyer{ public void makeFly(){ } } public class Bird extends Abc, Flyer{ public void doAnotherThing(){ } }
同样,类Flyer
隐式扩展了Object的方法toString()
,任何类都会有这个方法,因为它们都是间接扩展Object
,所以,如果从Bird
调用toString()
, toString()
java就不得不使用? 从美国Abc
还是Flyer
? 这将发生在任何试图扩展两个或更多类的类上,为了避免这种“方法碰撞”,他们构build了接口的概念,基本上你可以把它们想象成一个抽象类,它不会间接扩展Object 。 由于它们是抽象的,它们必须由一个类来实现,这个类是一个对象 (你不能单独实现一个接口,它们必须由一个类来实现),所以一切都会继续正常工作。
为了区分接口类,关键字实现仅仅保留用于接口。
你可以在同一个类中实现你喜欢的任何接口,因为它们不会默认扩展任何东西(但是你可以创build一个扩展另一个接口的接口,但是“父”接口不会扩展Object),所以接口是只是一个接口,他们不会遭受“ 方法签名colissions ”,如果他们做的编译器会向你发出警告,你只需要改变方法签名来修复它(签名=方法名称+ PARAMS +返回types) 。
public interface Flyer{ public void makeFly(); // <- method without implementation } public class Bird extends Abc implements Flyer{ public void doAnotherThing(){ } @Override public void makeFly(){ // <- implementation of Flyer interface } // Flyer does not have toString() method or any method from class Object, // no method signature collision will happen here }
Java只支持通过接口的多重inheritance。 一个类可以实现任意数量的接口,但只能扩展一个类。
不支持多重inheritance,因为它会导致致命的钻石问题。 但是,它可以被解决,但会导致复杂的系统,所以Java创始人已经放弃了多重inheritance。
在James Gosling于1995年2月发表的名为“Java:an Overview”的白皮书( 链接 )中给出了为什么Java不支持多inheritance的想法。
据高斯林说:
“JAVA省略了很多很less使用,很less理解,令人困惑的C ++特性,在我们的经验中带来了更多的悲伤而不是好处,主要由操作符重载(尽pipe它有方法重载),多inheritance和广泛的自动强制组成。
因为接口只是一个合同。 而一个类实际上是一个数据容器。
举例来说,A类有一个getSomething方法,B类有一个getSomething方法,而C类则延伸了A和B.如果有人叫C.getSomething,会发生什么? 没有办法确定调用哪个方法。
接口基本上只是指定实现类需要包含的方法。 一个实现多个接口的类只是意味着类必须实现所有接口的方法。 如上所述,Whci不会导致任何问题。
考虑Test1,Test2和Test3是三个类的场景。 Test3类inheritanceTest2和Test1类。 如果Test1和Test2类具有相同的方法,并且您从子类对象中调用该方法,那么调用Test1或Test2类的方法将具有不明确性,但是不存在接口的不明确性,因为在接口中没有实现。
您可以在oracle文档页面find有关多重inheritance的准确答案
-
状态的多重inheritance:能够从多个类inheritance字段
Java编程语言不允许你扩展多个类的一个原因是为了避免多态inheritance的问题,这就是inheritance多个类的字段的能力
如果允许多重inheritance,并且在通过实例化该类创build对象时,该对象将inheritance所有类的超类的字段。 这将导致两个问题。
- 如果来自不同超类的方法或构造函数实例化相同的字段呢?
- 哪个方法或构造函数优先?
-
实现的多重inheritance:能够从多个类inheritance方法定义
这种方法的问题: 名称冲突和模棱两可 。 如果子类和超类包含相同的方法名称(和签名),编译器无法确定要调用哪个版本。
但是,Java支持这种types的多重inheritance,它具有自Java 8发布以来引入的默认方法 。 Java编译器提供了一些规则来确定特定类所使用的默认方法。
有关解决钻石问题的更多详情,请参阅下面的SE post:
Java 8中的抽象类和接口有什么区别?
-
types的多重inheritance:一个类能够实现多个接口。
由于接口不包含可变字段,因此您不必担心由此处的多重状态inheritance导致的问题。
由于歧义问题,Java不支持多重inheritance,多path和混合inheritance:
Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass ie, class C , so C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ? So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.
多重inheritance
参考链接: https : //plus.google.com/u/0/communities/102217496457095083679