为什么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 {@Overridepublic void eat() {System.out.println("Cat Is Eating");}
}

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/75876.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker【安装、存储、镜像、仓库、网络、监控】

docker-0110.0.0.51docker-0210.0.0.52docker-0310.0.0.53 【1】docker安装 docker-01 [rootdocker-01 ~]# vim /etc/yum.conf [main] cachedir/var/cache/yum/$basearch/$releasever keepcache1 debuglevel2 logfile/var/log/yum.log exactarch1 obsoletes1 gpgcheck1 plugin…

常见历史漏洞之Thinkphp

常见历史漏洞之Thinkphp 一、介绍二、Thinkphp历史漏洞三、Thinkphp特征发现四、批量漏洞检测五、漏洞总结六、5.0.23版本案例演示 一、介绍 Thinkphp是一种开源框架。是一个由国人开发的支持windows/Unix/Linux等服务器环境的轻量级PHP开发框架。很多cms就是基于thinkphp二次开…

论文阅读- Uncovering Coordinated Networks on Social Media:Methods and Case Studies

链接:https://arxiv.org/pdf/2001.05658.pdf 目录 摘要: 引言 Methods Case Study 1: Account Handle Sharing Coordination Detection 分析 Case Study 2: Image Coordination Coordination Detection Analysis Case Study 3: Hashtag Sequen…

【问题随记】

ubuntu 14.04源更新(sources.list) deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ trusty-update…

Mac 安装不在 Apple 商店授权的应用程序

文章目录 一、场景介绍二、实操说明 一、场景介绍 在日常的工作生活中,发现一些好用的应用程序,但是出于某些原因,应用程序的开发者并没有将安装包上架到苹果商店。 那么这些优秀的应用程序下载安装以后就会出现如下弹框被拒之门外 二、实操…

SpringBoot3---核心特性---1、快速入门II

星光下的赶路人star的个人主页 要活出自己之后再被人理解 文章目录 1、核心技能1.1 常用注解1.1.1 组件注册1.1.2 条件注解1.1.3 属性绑定 1.2 YAML配置文件1.2.1 基本语法1.2.2 示例1.2.3 细节1.2.4 小技巧:lombok 1.3 日志配置1.3.1 简介1.3.2 日志格式1.3.3 记录…

Go语言在人工智能时代的崭露头角:为何越来越多公司选择使用Go语言?

🌷🍁 博主猫头虎 带您 Go to Golang Language.✨✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1…

router-view路由出口

这边文章主要讲router-view搭建后台管理系统的一个基本模板 一.创建自己的路由规则 1.新建文件夹src/router/index.js npm i vue-router3.6.5 2.配置好文件 import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter);// 1.创建…

CentOS7安装JDK8(实操版 | 源码安装和yum安装)

前言 查看此文章前强烈建议先看这篇文章:Java江湖路 | 专栏目录 该文章纪录的是CentOS安装JDK操作,每一步都有记录,争取每一位看该文章的小伙伴都能操作成功~ 方式一:yum安装 1、yum方式比较简单,一个命令就能搞定 y…

RF手机天线仿真介绍(一):金属边框天线和LDS天线

目录 简介LDS天线LDS天线仿真 金属边框天线金属边框天线仿真 简介 最早的手机是外置式天线,从NOKIA开始采用内置式天线,开始采用内置金属片(一般是0.1MM厚的不锈钢片冲压而成),随后为降低成本,后来改用FPC…

1-搭建一个最简单的验证平台UVM,已用Questasim实现波形!

UVM-搭建一个最简单的验证平台,已用Questasim实现波形 1,背景知识2,".sv"文件搭建的UVM验证平台,包括代码块分享3,Questasim仿真输出(1)compile all,成功!&…

DirectX12 3D立方体游戏编程选修作业-龙书

DirectX12 3D立方体游戏编程作业-龙书 作业效果配置描述文件参考书签 作业效果 配置描述文件 参考:龙书dx12 chapter-6 电子版在CSDN下载里直接下载的 配置:将龙书中的visual stdio2015修改为visual stdio2019; visual stdio2019组件选择: desktop dev…

亚马逊云科技七项生成式AI新产品生成式AI,为用户解决数据滞后等难题

7月27日,亚马逊云科技在纽约峰会上一连发布了七项生成式AI创新,涵盖了从底层硬件到工具、软件、再到生态的全方位更新,成为它在该领域迄今最全面的一次升级展示,同时也进一步降低了生成式AI的使用门槛。 亚马逊云科技凭借自身端到…

Excel如何把两列互换

第一步:选择一列 打开excel,选中一列后将鼠标放在列后,让箭头变成十字方向。 第二步:选择Shift键 按住键盘上的Shift键,将列往后移动变成图示样。 第三步:选择互换 完成上述操作后,松开鼠标两…

pytorch实战-图像分类(二)(模型训练及验证)(基于迁移学习(理解+代码))

目录 1.迁移学习概念 2.数据预处理 3.训练模型(基于迁移学习) 3.1选择网络,这里用resnet 3.2如果用GPU训练,需要加入以下代码 3.3卷积层冻结模块 3.4加载resnet152模 3.5解释initialize_model函数 3.6迁移学习网络搭建 3.…

Spring-1-透彻理解Spring XML的Bean创建--IOC

学习目标 上一篇文章我们介绍了什么是Spring,以及Spring的一些核心概念,并且快速快发一个Spring项目,实现IOC和DI,今天具体来讲解IOC 能够说出IOC的基础配置和Bean作用域 了解Bean的生命周期 能够说出Bean的实例化方式 一、Bean的基础配置 …

分页Demo

目录 一、分页对象封装 分页数据对象 分页查询实体类 实体类用到的utils ServiceException StringUtils SqlUtil BaseMapperPlus,> BeanCopyUtils 二、示例 controller service dao 一、分页对象封装 分页数据对象 import cn.hutool.http.HttpStatus; import com.…

适配器模式(Adapter)

适配器模式用于将一个接口转换成用户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。 Adapter is a structural design pattern that…

Android Studio 关于BottomNavigationView 无法预览视图我的解决办法

一、前言:最近在尝试一步一步开发一个自己的软件,刚开始遇到的问题就是当我们引用 com.google.android.material.bottomnavigation.BottomNavigationView出现了无法预览视图的现象,我也在网上查了很多中解决方法,最后在执行了如下…

三个主流数据库(Oracle、MySQL和SQL Server)的“单表造数

oracle 1.创建表 CREATE TABLE "YZH2_ORACLE" ("VARCHAR2_COLUMN" VARCHAR2(20) NOT NULL ENABLE,"NUMBER_COLUMN" NUMBER,"DATE_COLUMN" DATE,"CLOB_COLUMN" CLOB,"BLOB_COLUMN" BLOB,"BINARY_DOUBLE_COLU…