龙空技术网

为什么Java类不支持多继承而接口可以?

低调的干货君 429

前言:

如今咱们对“java接口允许多继承吗”大约比较关怀,姐妹们都需要学习一些“java接口允许多继承吗”的相关内容。那么小编也在网摘上汇集了一些对于“java接口允许多继承吗””的相关知识,希望咱们能喜欢,咱们一起来学习一下吧!

每个用Java的人都知道java不支持多继承,但为什么呢?无论从抽象还是多态等层面思考,感觉都是行得通的,那么为什么不支持呢?

很多人都是分析一旦一个类继承了多个父类,那么父类中如果有相同的成员变量和方法,就不好处理,如下图,这就是Diamond问题

      GrandParent f()       /     \      /       \Parent1 f()     Parent2 f()      \       /       \     /         Son f()

那么此时子类如果我们只引用 f(),编译器将无法决定它应该调用哪个 f()方法,但此说明不足以让人信服,比如可以强制要求子类必须覆写f()方法。

Java之父,James Gosling在1995年的一份白皮书中给出了关于为什么不支持多继承

“JAVA omits many rarely used, poorly understood, confusing features of C++ that in our experience bring more grief than benefit. This primarily consists of operator overloading (although it does have method overloading), multiple inheritance, and extensive automatic coercions.”

主要就是说,Gosling认为,多继承是一种很少使用,并且很容易混淆的特性,所以Java语言就像删除操作符重载特性一样删除了多继承这种特性。

也就是说java为了便于程序员理解和使用,去除了一些不容易理解的特性,例如类的多继承。并非不能实现。

那为什么接口可以呢?

针对于Diamond(钻石)问题,接口由于本身都是抽象方法,继承谁都无所谓,都是需要其实现类去实现的,故不存在此问题。

此时有人问了,jdk1.8以后,java接口被赋予了一个新的功能,可以通过default关键字定义非抽象方法,那如果出现一个接口继承的父接口有相同的非抽象方法怎么办呢?

下面我们看看jdk1.8中如何处理

public interface Aservice {    void say();    default void bye(){        System.out.println("a service say bye");    }}public interface Bservice {    void say();    default void bye(){        System.out.println("b service say bye");    }}

此时我们定义接口去继承,如下图,发现被强制要求覆写相同的非抽象方法,以保证编译器知道具体执行哪个方法。

因此接口是可以的多继承的,即使jdk1.8中添加了非抽象方法。

标签: #java接口允许多继承吗