Java接口如何模拟多重继承?

Java接口如何模拟多重继承?,java,interface,multiple-inheritance,Java,Interface,Multiple Inheritance,我正在阅读“Java教程”(第二次)。我刚刚(再次)读完了关于接口的部分,但仍然不理解Java接口是如何模拟多重继承的。有没有比书中更清楚的解释 这很简单。一个类型中可以实现多个接口。例如,您可以有一个List的实现,它也是Deque的一个实例(Java有…LinkedList) 您不能从多个父级继承实现(即扩展多个类)。声明(方法签名)没有问题。它不是多重继承的模拟。在java中,您不能从两个类继承,但是如果您实现了两个接口,“看起来您是从两个不同的类继承的”,因为您可以将您的类用作两个接口中

我正在阅读“Java教程”(第二次)。我刚刚(再次)读完了关于接口的部分,但仍然不理解Java接口是如何模拟多重继承的。有没有比书中更清楚的解释

这很简单。一个类型中可以实现多个接口。例如,您可以有一个
List
的实现,它也是
Deque
的一个实例(Java有…
LinkedList


您不能从多个父级继承实现(即扩展多个类)。声明(方法签名)没有问题。

它不是多重继承的模拟。在java中,您不能从两个类继承,但是如果您实现了两个接口,“看起来您是从两个不同的类继承的”,因为您可以将您的类用作两个接口中的任何一个

比如说

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,这看起来像是一种多重继承,但这并不是因为您不继承任何东西,您只需重写接口提供的公共方法。

我认为它们不会

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


我相信这里有一个关于接口和多重继承的问题,但我现在找不到它…

说接口“模拟”多重继承是不公平的

当然,您的类型可以实现多个接口,并以多态方式充当许多不同的类型。然而,在这种安排下,您显然不会继承行为或实现

通常在您认为可能需要多重继承的情况下查看组合


或者实现多重继承的潜在解决方案是Mixin接口-。小心使用

鉴于下面的两个接口

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");
  }
}

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

Java中确实没有模拟多重继承


人们有时会说,可以使用接口模拟多继承,因为每个类可以实现多个接口,然后使用组合(而不是继承)在您的类中实现您试图从中继承的多个类的行为。

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


接口允许类型的多重继承,例如,
类Waterfowl extends Bird implements Swimmer
可以被其他类使用,就像它是
鸟一样,就像它是
游泳者一样。这就是多重继承的深层含义:允许一个对象同时表现为它属于几个不相关的不同类。

假设您的域中有两种东西:卡车和厨房

卡车有driveTo()方法,厨房有cook()方法

现在假设Pauli决定从送货车后面卖比萨饼。他想要一种可以开车去做饭的东西

<>在C++中,他会使用多重继承来完成这个操作。 在Java中,这被认为是非常危险的,因此您可以从一个主类继承,但您可以从接口“继承”行为,这些接口出于所有目的都是抽象类,没有字段或方法实现

因此,在Java中,我们倾向于使用委托实现多重继承:

Pauli将一个truck子类化,并在名为kitchen的成员变量中向truck添加一个厨房。他通过调用Kitchen.cook()来实现厨房接口

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

pizzaTruck.driveTo(beach);
pizzaTruck.cook(pizzaWithExtraAnchovies);
好的,这个愚蠢的故事是为了说明它不是多重继承的模拟,它是真正的多重继承,附带条件是你只能继承契约,只能继承空的抽象基类,这些基类被称为接口


(更新:随着现在的到来,还可以提供一些可继承的行为)

您需要精确:

Java允许接口的多重继承,但只允许实现的单一继承

在Java中执行接口的多重继承,如下所示:

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创建者认为多重继承是错误的,所以Java中没有这种东西

如果要将两个类的功能组合为一个类,请使用对象组合。即

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}
如果要公开某些方法,请定义它们并让它们将调用委托给相应的控制器

这里的接口可能很方便-如果
Component1
实现接口
Interface1
Component2
实现
Interface2
,您可以定义

class Main implements Interface1, Interface2
因此,您可以在上下文允许的情况下互换使用对象。

它们不允许

我认为这种混乱来自于人们认为实现接口构成某种形式的继承。事实并非如此;实现可以是空白的,没有行为是由行为强制的,也没有任何合同保证的。一个典型的例子是Clonable接口,它虽然暗指了很多伟大的功能,但定义得太少,以至于它基本上是无用的,并且有潜在的危险

你继承了什么
class Main implements Interface1, Interface2
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();
    }

}
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();
}
public class SharedFeature<T> extends <T extends Activity>

...
...
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 {
   ...
};
class ForestHerbivore implements Herbivore
    void munch(Vegetable v) { ... }
};

class ForestCarnivore implements Carnivore
    void devour(Prey p) { ... }
};
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); }
}
interface AllEater {
    Herbivore asHerbivore();
    Carnivore asCarnivore();
}
interface ParentOne{
   public String parentOneFunction();
}

interface ParentTwo{
    public String parentTwoFunction();
}

class Child implements ParentOne,ParentTwo{

   @Override
    public String parentOneFunction() {
        return "Parent One Finction";
    }

    @Override
    public String parentTwoFunction() {
        return "Parent Two Function";
    }

    public String childFunction(){
       return  "Child Function";
    }
}
public class MultipleInheritanceClass {
    public static void main(String[] args) {
        Child ch = new Child();
        System.out.println(ch.parentOneFunction());
        System.out.println(ch.parentTwoFunction());
        System.out.println(ch.childFunction());
    }
}