为什么Java不支持多继承?

面试回答

因为如何要实现多继承,就会像C++中一样,存在菱形继承的问题,C++为了解决菱形继承问题,又引入了虚继承。因为支持多继承,引入了菱形继承问题,又因为要解决菱形继承问题,引入了虚继承。而经过分析,人们发现我们其实真正想要使用多继承的情况并不多。所以,在 Java 中,不允许“多继承”,即一个类不允许继承多个父类。

在 Java 8 以前,接口中是不能有方法的实现的。所以一类同时实现多个接口的时候,也不会出现 C++中的歧义问题。因为所有的方法都没有方法体,真正的实现还是在子类中的。但是,Java 8 中支持了默认函数(default method),即接口中可以定义一个有方法体的方法了。

而又因为 Java 支持同时实现多个接口,这就相当于通过 implements 就可以从多个接口中继承到多个方法了,但是,Java8 中为了避免菱形继承的问题,在实现的多个接口中如果有相同方法,就会要求该类必须重写这个方法。

知识扩展

菱形继承问题

Java 的创始人 James Cosling 曾经回答过,他表示:

“Java之所以不支持一个类继承多个类,主要是因为在设计之初我们听取了来自C++和Objective-C等阵营的人的意见。因为多继承会产生很多歧义问题。”

Gosling 老人家提到的歧义问题,其实是 C++ 因为支持多继承之后带来的菱形继承问题。

假设我们有类B和类C,它们都继承了相同的类 A。另外我们还有类D,类D通过多重继承机制继承了类B和类C。

这时候,因为D同时继承了B和C,并且B和C又同时继承了A,那么,D中就会因为多重继承,继承到两份来自A中的属性和方法。

这时候,在使用D的时候,如果想要调用一个定义在A中的方法时,就会出现歧义。

因为这样的继承关系的形状类似于菱形,因此这个问题被形象地成为菱形继承问题。

而C++为了解决菱形继承问题,又引入的虚继承

因为支持多继承,引入了菱形继承问题,又因为要解决菱形继承问题,引入了虚继承,人们发现我们其实真正想要使用多继承的情况并不多。

所以,在Java中,不允许“声明多继承”,即一个类不允许继承多个父类。但是允许“实现多继承”,即一个类可以实现多个接口,一个接口也可以继承多个父接口。由于接口只允许有方法声明而不允许有方法实现(Java8 之前),这就避免了 C++ 中继承的歧义问题。

Java 8 中的多继承

Java 不支持多继承,但是是支持多实现的,也就是说,同一个类可以同时实现多个类。

我们知道,在 Java8以前,接口中是不能有方法的实现的。所以一个类同时实现多个接口的话,也不会出现 C++中的歧义问题。因为所有方法都没有方法体,真正的实现还是在子类中的。

那么问题来了。

Java 8 中支持了默认函数(default method),即接口中可以定义一个有方法体的方法了。

public interface Pet {

    public default void eat(){
        System.out.println("Pet Is Eating");
    }
}

而又因为Java支持同时实现多个接口,这就相当于通过 implements 就额可以从多个接口中继承到多个方法了,这不就是变相支持了多继承么。

那么,Java 是怎么解决菱形继承问题的呢?我们再定义一个哺乳动物接口,也定义一个eat方法。

public interface Mammal {

    public default void eat(){
        System.out.println("Mammal Is Eating");
    }
}

然后定义一个 Cat ,让他分别实现两个接口。

public class Cat implements Pet, Mammal {

}

这时候,编译器会报错:

java: 类 com.chiyi.service.impl.Cat从类型 com.chiyi.service.Pet 和 com.chiyi.service.Mammal 中继承了eat() 的不相关默认值

这时候,就要求 Cat 类中,必须重写 eat() 方法。

public class Cat implements Pet, Mammal {
    @Override
    public void eat() {
        System.out.println("Cat Is Eating");
    }
}

所以可以看到,Java 并没有帮我们解决多继承的歧义问题,而是把这个问题留给开发人员,通过重写方法的方式自己解决。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

协享科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值