Java接口如何模拟多重inheritance?

我正在阅读“Java教程”(第二次)。 我刚刚通过Interfaces(再次)的一节,但仍不明白Java接口如何模拟多重inheritance。 有没有比书中更清楚的解释?

假设你在你的领域有两种东西:卡车和厨房

卡车有一个driveTo()方法和Kitchens一个cook()方法。

现在假设泡利决定从货车后面卖披萨。 他想要一个可以开车去()和做饭()的东西。

在C ++中,他会使用多重inheritance来做到这一点。

在Java中被认为是太危险了,所以你可以从一个主类inheritance,但是你可以从接口inheritance行为,这些接口是用于所有意图和目的的抽象类,没有字段或方法实现。

所以在Java中,我们倾向于使用委托实现多重inheritance:

泡利将一辆卡车分类,并在一个名为厨房的成员variables中为卡车添加了一个厨房。 他通过调用kitchen.cook()来实现Kitchen界面。

class PizzaTruck extends Truck implements Kitchen { Kitchen kitchen; public void cook(Food foodItem) { kitchen.cook(foodItem); } } 

他是一个快乐的人,因为他现在可以做这样的事情;

 pizzaTruck.driveTo(beach); pizzaTruck.cook(pizzaWithExtraAnchovies); 

好吧,这个愚蠢的故事是为了说明它不是多重inheritance的模拟,它是真正的多重inheritance,但是只能inheritance契约,只能从被称为接口的空抽象基类inheritance。

(更新:现在接口的缺省方法也可以提供一些被inheritance的行为)

您可能会感到困惑,因为您在本地查看多个inheritance,就一个类从多个父项inheritance实现细节而言。 这在Java中是不可能的(并且经常导致在可能的语言中滥用)。

接口允许types的多重inheritance,例如一个class Waterfowl extends Bird implements Swimmer可以被其他类使用,就好像它是一个Bird 就好像它是一个Swimmer 。 这是多重inheritance的深层含义:允许一个对象像它一样属于几个不相关的不同类。

这是通过java中的接口实现多重inheritance的一种方法。

要实现什么?
类A扩展B,C //这在Java中不可能直接使用,但可以间接实现。

 class B{ public void getValueB(){} } class C{ public void getValueC(){} } interface cInterface{ public getValueC(); } class cChild extends C implemets cInterface{ public getValueC(){ // implementation goes here, call the super class's getValueC(); } } // Below code is **like** class A extends B, C class A extends B implements cInterface{ cInterface child = new cChild(); child.getValueC(); } 

接口不模拟多重inheritance。 Java创build者认为多重inheritance是错误的,所以在Java中没有这样的东西。

如果你想把两个类的function组合成一个使用对象组合。 即

 public class Main { private Component1 component1 = new Component1(); private Component2 component2 = new Component2(); } 

如果您想公开某些方法,请定义它们并让它们将调用委托给相应的控制器。

这里的接口可能会得心应手 – 如果Component1实现接口Interface1Component2实现Interface2 ,则可以定义

 class Main implements Interface1, Interface2 

这样你就可以在上下文允许的情况下交替使用对象。

给出下面的两个接口…

 interface I1 { abstract void test(int i); } interface I2 { abstract void test(String s); } 

我们可以使用下面的代码来实现这两个…

 public class MultInterfaces implements I1, I2 { public void test(int i) { System.out.println("In MultInterfaces.I1.test"); } public void test(String s) { System.out.println("In MultInterfaces.I2.test"); } public static void main(String[] a) { MultInterfaces t = new MultInterfaces(); t.test(42); t.test("Hello"); } } 

我们不能扩展两个对象,但是我们可以实现两个接口。

你知道什么,从一个JavaScript开发者的angular度来看,试图了解这个东西到底是怎么回事,我想指出一些事情,有人请告诉我我在这里错过了什么,如果我脱颖而出。

接口非常简单。 愚蠢,疯狂简单。 它们像人们最初想象的那样愚蠢简单,这就是为什么在这个确切的主题上有这么多重复的问题,因为使用它们的一个原因已经被试图使它们比它们更多和更多的人弄得不清楚在我所接触过的每个Java服务器端代码库中都被广泛滥用。

那么,你为什么要使用它们呢? 大多数时候你不会。 你当然不会像很多人想象的那样一直使用它们。 但是,在我想到的时候,让我们来谈谈他们不是什么。

接口不是:

  • 以任何方式解决Java缺乏的任何types的inheritance机制。 他们与inheritance无关,他们从来没有做过,也没有模仿任何inheritance类。
  • 必然是可以帮助你处理你写的东西的东西,这样可以帮助另一个人写一些东西,以便与你的东西交互。

他们真的很简单,你认为他们乍一看。 人们总是愚蠢地滥用,所以很难理解这一点。 这只是validation/testing。 一旦你写了一个符合接口的东西并且工作,删除那个“实现”代码将不会破坏任何东西。

但是,如果你正确地使用接口,你不会想要删除它,因为在那里为下一个开发者提供了一个工具来编写另一组数据库或Web服务的访问层,他们希望你的应用程序的其余部分继续使用,因为他们知道他们的类将失败,直到他们得到100%完成预期的接口。 所有的接口都是validation你的类,并确定你已经实现了一个接口,如你所承诺的那样。 而已。

他们也是便携式的。 通过暴露你的接口定义,你可以给那些想要使用未暴露的代码的人一套方法来使它们的对象正确地使用它。 他们不必实现接口。 他们可以把它们记在一张记事本纸上,仔细检查一下。 但是对于界面来说,你有更多的保证,只有当它有适当的接口版本时,才会尝试工作。

那么,任何不太可能实现的接口不止一次? 完全没用。 多重inheritance? 别去找那个彩虹了 Java首先避免了它们,无论如何,合成/聚合对象在很多方面都更加灵活。 这并不是说接口不能帮助你用多重inheritance的方式进行build模,但它不是以任何forms或formsinheritance,不应该被看作是这样的。 这只是保证你的代码不会运行,直到你实现了你所build立的所有方法。

这很简单。 你可以在一个types中实现多个接口。 所以举个例子,你可以有一个List的实现,它也是Deque一个实例(和Java的… LinkedList )。

你不能inheritance多个父母的实现 (即扩展多个类)。 声明 (方法签名)是没有问题的。

这不是一个多重inheritance的模拟。 在Java中,你不能从两个类inheritance,但是如果你实现了两个接口“看起来像你从两个不同的类inheritance”,因为你可以使用你的类作为你的任何两个接口。

例如

 interface MyFirstInteface{ void method1(); } interface MySecondInteface{ void method2(); } class MyClass implements MyFirstInteface, MySecondInteface{ public void method1(){ //Method 1 } public void method2(){ //Method 2 } public static void main(String... args){ MyFirstInterface mfi = new MyClass(); MySecondInterface msi = new MyClass(); } } 

这将工作,你可以使用mfi和msi,它似乎是一个多inheritance,但这不是因为你没有inheritance任何东西,你只是重写接口提供的公共方法。

你需要精确:

Java允许接口的多重inheritance,但只能实现单一的inheritance。

你可以像这样在Java中进行多接口的inheritance:

 public interface Foo { String getX(); } public interface Bar { String getY(); } public class MultipleInterfaces implements Foo, Bar { private Foo foo; private Bar bar; public MultipleInterfaces(Foo foo, Bar bar) { this.foo = foo; this.bar = bar; } public String getX() { return this.foo.getX(); } public String getY() { return this.bar.getY(); } } 

顺便说一下,Java没有实现完全多重inheritance的原因是因为它造成了模糊性。 假设你可以说“A扩展B,C”,然后B和C都有一个函数“void f(int)”。 Ainheritance了哪个实现? 用Java的方法,你可以实现任意数量的接口,但接口只能声明一个签名。 因此,如果两个接口包含具有相同签名的函数,那么您的类必须实现具有该签名的函数。 如果你inheritance的接口具有不同签名的function,那么这些function就没有任何关系,所以不存在冲突的问题。

我不是说这是唯一的方法。 C ++通过build立哪个实现获胜的优先规则来实现真正的多重inheritance。 但是Java的作者决定消除这种模糊性。 无论是因为哲学上的信念,这是为了更清晰的代码,还是因为他们不想做所有额外的工作,我都不知道。

说接口“模拟”多重inheritance是不公平的。

当然,你的types可以实现多个接口,并且可以多态地处理许多不同的types。 然而,你显然不会在这种安排下inheritance行为或实现。

一般看你认为你可能需要多重inheritance的组合。

或者像一个Mixin接口 – http://csis.pace.edu/~bergin/patterns/multipleinheritance.html ,实现多重inheritance的潜在解决scheme。 小心使用!

他们没有。

我认为混淆来自人们认为实现一个接口构成某种forms的inheritance。 它不; 实施可以简单地是空白的,没有任何行为是由行为强制或通过任何合同保证。 一个典型的例子就是Clonable接口,虽然提到了很多很棒的function,但它定义的很less,实质上是无用的,有潜在危险。

你通过实现一个接口inheritance了什么? Bubkes! 所以在我看来,停止在同一个句子中使用界面和inheritance的话。 正如Michael Borgwardt所说,接口不是一个定义,而是一个方面。

如果他们自己实现接口,你可以实际上从多个具体类“inheritance”。 innerclasses帮助你实现这个目标:

 interface IBird { public void layEgg(); } interface IMammal { public void giveMilk(); } class Bird implements IBird{ public void layEgg() { System.out.println("Laying eggs..."); } } class Mammal implements IMammal { public void giveMilk() { System.out.println("Giving milk..."); } } class Platypus implements IMammal, IBird { private class LayingEggAnimal extends Bird {} private class GivingMilkAnimal extends Mammal {} private LayingEggAnimal layingEggAnimal = new LayingEggAnimal(); private GivingMilkAnimal givingMilkAnimal = new GivingMilkAnimal(); @Override public void layEgg() { layingEggAnimal.layEgg(); } @Override public void giveMilk() { givingMilkAnimal.giveMilk(); } } 

我不认为他们这样做。

inheritance特别是实现之间的面向实现的关系。 接口根本不提供任何实现信息,而是定义一个types。 为了inheritance,您需要特别从父类inheritance一些行为或属性。

我相信这里有一个关于接口和多重inheritanceangular色的具体问题,但现在我找不到它了。

Java中没有多重inheritance的模拟。

人们有时会说,你可以使用接口来模拟多重inheritance,因为你可以为每个类实现多个接口,然后在你的类中使用组合(而不是inheritance)来实现你试图inheritance的多个类的行为开始。

如果它在你的对象模型中是有意义的,你当然可以从一个类inheritance,并实现一个或多个接口。

有些情况下,多重inheritance变得非常方便,而且不用编写更多的代码就很难用接口replace。 例如,有一些Android应用程序使用派生自Activity的类和来自同一应用程序中FragmentActivity的其他类。 如果您想要在普通类中共享某个特定function,则必须在Java中复制代码,而不是让Activity和FragmentsActivity的子类从相同的SharedFeature类派生。 在Java中generics的不好的实现也没有帮助,因为编写以下是非法的:

 public class SharedFeature<T> extends <T extends Activity> ... ... 

java中不支持多inheritance。

这个使用接口支持多重inheritance的故事是我们开发人员熟悉的。 接口比具体类提供了灵活性,我们可以select使用单个类来实现多个接口。 这是通过协议我们正在坚持两个蓝图创build一个类。

这是试图接近多重inheritance。 我们所做的是实现多个接口,在这里我们不扩展(inheritance)任何东西。 实现类是要添加属性和行为的类。 它没有从父类中获得实现。 我只是简单的说,在java中不支持多inheritance。

我想指出一些背后的东西,来自C ++,你可以很容易地inheritance许多实现。

有很多方法的“宽”接口意味着你将不得不在你的具体类中实现很多方法,你不能在实现中轻松地共享这些方法

例如:

 interface Herbivore { void munch(Vegetable v); }; interface Carnivore { void devour(Prey p); } interface AllEater : public Herbivore, Carnivore { }; class Fox implements AllEater { ... }; class Bear implements AllEater { ... }; 

在这个例子中,福克斯和熊不能共享一个共同的基础实现,无论是它的接口方法munchdevour

如果基本实现看起来像这样,我们可能会想要使用它们的FoxBear

 class ForestHerbivore implements Herbivore void munch(Vegetable v) { ... } }; class ForestCarnivore implements Carnivore void devour(Prey p) { ... } }; 

但是我们不能inheritance这两个。 基类实现需要成为类中的成员variables,定义的方法可以转发给它。 即:

 class Fox implements AllEater { private ForestHerbivore m_herbivore; private ForestCarnivore m_carnivore; void munch(Vegetable v) { m_herbivore.munch(v); } void devour(Prey p) { m_carnivore.devour(p); } } 

如果接口增长(即超过5-10个方法…),这将变得很难处理

更好的方法是将接口定义为接口的聚合:

 interface AllEater { Herbivore asHerbivore(); Carnivore asCarnivore(); } 

这意味着FoxBear只需要实现这两个方法,而接口和基类可以独立增长到与实现类相关的聚合AllEater接口。

如果它适用于您的应用程序,那么这种方式更less耦合。

不,Java不支持多重inheritance。 既不使用类也不使用接口。 请参阅此链接了解更多信息https://devsuyed.wordpress.com/2016/07/21/does-java-support-multiple-inheritance

我也不得不说,Java不支持多重inheritance。

你必须在Java中区分extendsimplements关键字的含义。 如果我们使用extends ,我们实际上是inheritance关键字后面的类。 但是,为了使一切变得简单,我们不能多次使用extends 。 但是你可以按照你的意愿实现尽可能多的接口。

如果你实现了一个接口,那么你很可能会错过每个接口中所有方法的实现(例外:在Java 8中引入的接口方法的默认实现)所以,现在你已经完全意识到事情正在发生什么你已经embedded到你的新class级。

为什么Java不允许多重inheritance,实际上,多重inheritance使得代码有些复杂。 有时,由于具有相同的签名,父类的两种方法可能会发生冲突。 但是如果你被迫手动执行所有的方法,你将会对上面提到的事情有充分的了解。 它使你的代码对你更容易理解。

如果您需要更多有关Java接口的信息,请查看本文, http://www.geek-programmer.com/introduction-to-java-interfaces/