Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java中没有多重继承,但允许实现多个接口?_Java_Oop_Inheritance_Interface_Language Design - Fatal编程技术网

为什么Java中没有多重继承,但允许实现多个接口?

为什么Java中没有多重继承,但允许实现多个接口?,java,oop,inheritance,interface,language-design,Java,Oop,Inheritance,Interface,Language Design,Java不允许多重继承,但它允许实现多个接口。为什么?因为接口只是一个契约。类实际上是数据的容器。出于同样的原因,C#不允许多重继承,但允许实现多重接口 < C++ >多元继承的教训是,它导致的问题多于它的价值。 接口是类必须实现的东西的契约。您不会从界面获得任何功能。继承允许您继承父类的功能(在多重继承中,这可能会非常混乱) 允许多个接口允许您使用设计模式(如适配器)来解决您可以使用多个继承解决的相同类型的问题,但以更可靠和更可预测的方式解决。因为接口只指定类正在做什么,而不指定类如何做 多重

Java不允许多重继承,但它允许实现多个接口。为什么?

因为接口只是一个契约。类实际上是数据的容器。

出于同样的原因,C#不允许多重继承,但允许实现多重接口

< C++ >多元继承的教训是,它导致的问题多于它的价值。

接口是类必须实现的东西的契约。您不会从界面获得任何功能。继承允许您继承父类的功能(在多重继承中,这可能会非常混乱)


允许多个接口允许您使用设计模式(如适配器)来解决您可以使用多个继承解决的相同类型的问题,但以更可靠和更可预测的方式解决。

因为接口只指定类正在做什么,而不指定类如何做


多重继承的问题是,两个类可能定义做同一件事的不同方式,而子类无法选择要选择的方式。

因为继承被过度使用,即使你不能说“嘿,这个方法看起来很有用,我也会扩展这个类”


实现多个接口非常有用,不会给语言实现者或程序员带来太多问题。所以这是允许的。多重继承虽然也很有用,但会给用户带来严重问题(可怕)。使用多重继承所做的大多数事情也可以通过组合或使用内部类来完成。因此,多重继承是被禁止的,因为它带来的问题多于收益。

我的一位大学导师这样向我解释:

假设我有一个类,是烤面包机,还有一个类,是NuclearBomb。它们都可能有一个“黑暗”设置。它们都有一个on()方法。(一个有off(),另一个没有。)如果我想创建一个类,它是这两个类的子类……正如你所看到的,这是一个可能会在我面前爆发的问题

因此,主要问题之一是,如果您有两个父类,它们可能具有相同功能的不同实现,或者可能具有相同名称的两个不同功能,如我的讲师的示例所示。然后,您必须决定您的子类将使用哪一个。当然,有很多方法可以处理这个问题——C++是这样做的,但是java设计者觉得这会使事情变得太复杂。
不过,通过接口,您可以描述类能够完成的任务,而不是借用另一个类的方法来完成任务。与多个父类相比,多个接口引起需要解决的棘手冲突的可能性要小得多。

例如,类A有一个getSomething方法,类B有一个getSomething方法,类C扩展了A和B。如果有人调用C.getSomething,会发生什么?无法确定要调用哪个方法


接口基本上只是指定实现类需要包含哪些方法。实现多个接口的类只意味着该类必须实现来自所有这些接口的方法。Whci不会导致上述任何问题。

据说对象状态是相对于其中的字段引用的,如果继承了太多的类,则会变得不明确。这里是链接


考虑一个场景,其中Test1、Test2和Test3是三个类。Test3类继承Test2和Test1类。如果Test1和Test2类有相同的方法,并且您从子类对象调用它,那么调用Test1或Test2类的方法会有歧义,但接口不会有歧义,因为接口中没有实现。

由于本主题没有结束,我将发布此答案,我希望这能帮助人们理解为什么java不允许多重继承

考虑以下类别:

public class Abc{

    public void doSomething(){

    }

}
public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}
在这种情况下,Abc类没有扩展任何内容,对吗?不是很快,这个类隐式地扩展了类对象,这个基类允许一切在java中工作。一切都是对象

如果您尝试使用上面的类,您将看到您的IDE允许您使用以下方法:
equals(Object o)
toString()
,等等,但是您没有声明这些方法,它们来自基类
Object

你可以试试:

public class Abc extends String{

    public void doSomething(){

    }

}
这很好,因为您的类不会隐式扩展
对象
,而是会扩展
字符串
,因为您已经说过了。考虑以下变化:

public class Abc{

    public void doSomething(){

    }

    @Override
    public String toString(){
        return "hello";
    }

}
现在,如果调用toString(),您的类将始终返回“hello”

现在想象一下下面的课程:

public class Abc{

    public void doSomething(){

    }

}
public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}
同样,类
Flyer
隐式扩展对象,该对象具有方法
toString()
,任何类都将具有此方法,因为它们都间接扩展
Object
,因此,如果从
Bird
调用
toString()
,java必须使用哪个
toString()
?从
Abc
Flyer
?任何试图扩展两个或多个类的类都会发生这种情况,为了避免这种“方法冲突”,他们构建了接口的思想,基本上你可以认为它们是一个抽象类,不会间接扩展对象。由于它们是抽象的,它们必须由类来实现,而类是对象(不能单独实例化接口,它们必须由类来实现),因此一切都将继续正常工作

为了使类与接口不同,关键字implements仅为接口保留

您可以在同一个类中实现您喜欢的任何接口,因为它们不扩展任何对象b
 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 i.e., 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.
 class C extends A, B // for explaining purpose.
public class Bank {
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank{
 public void printBankBalance(){
    System.out.println("20k");
  }
}
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");
  }
}
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");
  }
}