Java三大特性之二——继承(工作、面试、学习必备技能)

news2024/11/23 12:46:21

目录

继承的概述

 继承的特点

 继承中的成员变量

 继承中的成员方法

 方法的重写

继承中的构造方法

 super关键字 

super和this的区别

继承的概述

  • 多个类中存在相同属性(成员变量)和行为(方法)时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
  • 子类可以直接访问父类中的非私有的属性和行为。
  • 通过 extends 关键字让类与类之间产生继承关系。

        –class SubDemo extends Demo{}  SubDemo是子类,Demo是父类

package com.demo01;
/*
 * 继承:多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,我们的多个类就可以获取到父类中的成员了。
 * extends
 * 
 */
public class ExtendsDemo {
	public static void main(String[] args) {
		DotA d = new DotA();
		d.start();
		
		LOL l = new LOL();
		l.start();
	}
}
// 父类
class Game {
	String name;
	double version;//版本号
	String agent;//代理商
	
	//法
	public void start() {
		System.out.println("游戏启动了");
	}
	
	public void stop() {
		System.out.println("游戏关闭了");
	}
}

//子类 继承了游戏所有的属性和方法
class DotA extends Game {

}

//子类 继承了游戏所有的属性和方法
class LOL extends Game {

}

代码分析:我们创建一个游戏父类——class game,我们创建了DotA、LOL子类来继承游戏的父类,继承了游戏的所有属性和方法,我们创建两个子类对象,执行父类里边的东西。

结果显示:

 继承的特点

  • Java只支持单继承,不支持多继承。

        –一个类只能有一个父类,不可以有多个父类。

        –class SubDemo extends Demo{} //ok

        –class SubDemo extends Demo1,Demo2...//这种是错误的

  • Java支持多层继承(继承体系)

        –class A{}

        –class B extends A{}

        –class C extends B{}

        声明一个父类:A,子类B可以继承C,子类C也可以继承子类B,也就是说一个类既可以当子类,也可以当父类。

package com.demo02;
/*
 * Java中继承的特点:
 * 			Java语言只支持单一继承,只能继承一个父类(一个儿子只能有一个亲爹)
 * 			Java语言支持多层继承(一个儿子可以有一个亲爹,还可以有一个亲爷爷)
 * 
 */
public class ExtendsDemo2 {
	public static void main(String[] args) {
		LOL l = new LOL();
		MobileGame s = new MobileGame();
		l.update();
		l.start();
		s.update();
		s.start();
	}
}

class Game {
	public void start() {
		System.out.println("游戏启动了");
	}
}

class PCGame extends Game {
	public void update() {
		System.out.println("PCGame更新了");
	}
}

class MobileGame extends Game {
	public void update() {
		System.out.println("MobileGame更新了");
	}
}

class LOL extends PCGame {
	
}

代码分析:我们创建了一个父类,为Game, 其中子类PCGame和MobileGame都继承了父类Game——作为爷爷级别,而LOL又继承了PCGame——作为爸爸类,我们new一个LOL对象。

结果显示:

 继承中的成员变量

  • 如果子父类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;访问父类中的同名变量 用super
  • super的使用和this的使用几乎一致
  • this代表的是本类对象的引用;super当前子类对象父类的引用。

继承中成员变量的特点:

子类只能获取父类非私有成员

子父类中成员变量的名字不一样,直接获取父类的成员变量

子父类中成员变量名字是一样的,获取的是子类的成员变量

package com.demo02;
/*
 * 继承中成员变量的特点
 * 		子类只能获取父类非私有成员
 * 		子父类中成员变量的名字不一样,直接获取父类的成员变量
 * 		子父类中成员变量名字是一样的,获取的是子类的成员变量
 * 
 * 就近原则:谁离我近我就用谁
 * 		如果有局部变量就使用局部变量
 * 		如果没有局部变量,有子类的成员变量就使用子类的成员变量
 * 		如果没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量
 * 		啥都没有,出错了!!!
 * 
 * super:可以获取父类的成员变量和成员方法,用法和this是相似的
 */
public class ExtendsDemo3 {
	public static void main(String[] args) {
		Kid3 k = new Kid3();
		k.show();
	}
}

class Dad3 {
	String name = "建霖";
	String superName = "父类中的成员变量";
}

class Kid3 extends Dad3 {
	String name = "四葱";
	
	public void show() {
		System.out.println(super.superName);
		
		String name = "五葱";
		
		//System.out.println(super.name);
		System.out.println(this.name);
		System.out.println(name);
	}
}

代码分析:创建一个父类——Dad3,成员变量是name,superName,在子类中Kid3也有name,要想访问子类中的成员变量name,要用this,而子类中要想访问父类中的superName,要用super,而访问局部变量,不用this,采用的是就近原则。

 继承中的成员方法

  • 当子类出现和父类一模一样的方法时,当子类对象调用该方法,会运行子类方法的内容。如同父类的方法被覆盖一样。
  • 这种情况是方法的另一个特性:
  • 重写(覆盖)(override)
  • 重载overload

 继承中成员方法的特点:

子类中没有这个方法,调用父类的

子类中重写了这个方法,调用子类的

方法的重写(override):在子父类当中,子类的方法和父类的完全一样,子类重写了父类的方法(覆盖),当子类重写了父类的方法之后,使用子类对象调用的就是子类的方法

方法的重载(overload):在一个类中,有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关

package com.demo02;
/*
 * 继承中成员方法的特点
 * 		子类中没有这个方法,调用父类的
 * 		子类中重写了这个方法,调用子类的
 * 
 
 	方法的重写(override):在子父类当中,子类的方法和父类的完全一样,子类重写了父类的方法(覆盖),当子类重写了父类的方法之后,使用子类对象调用的就是子类的方法
 	方法的重载(overload):在一个类中,有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关
 
 */
public class ExtendsDemo4 {
	public static void main(String[] args) {
		Kid4 k = new Kid4();
		k.eat();
		k.eat(null);
	}
}

class Dad4 {
	public void eat() {
		System.out.println("小酌两口");
		System.out.println("去睡觉了");
	}
}

class Kid4 extends Dad4 {
	public void eat() {
		super.eat();
		System.out.println("好好吃饭");
	}
	
	public void eat(String name) {
		super.eat();
		System.out.println("好好吃饭1");
	}
}

代码分析:定义了一个父类——Dad4,里边定义了一个eat()方法,定义了一个子类Kid4继承父类Dad4,也定义了一个eat()方法,和父类的方法一致,用super来调用父类的方法,创建一个类对象,执行程序,先执行父类,再执行子类。

 方法的重写

  • 子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
  • 父类中的私有方法可不可以被覆盖呢?子类根本就看不到父类的方法
  • 在子类覆盖方法中,继续使用被覆盖的方法可以通过super.方法名获取。
  • 覆盖注意事项:

        –覆盖时,子类方法权限一定要大于等于父类方法权限

  • 覆盖的应用:

        –当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

package com.demo03;
/*
 * 	方法重写的应用场景:当父类的方法不能完全满足子类使用,这个时候子类重写父类的方法,
 * 				    并可以在方法中使用关键字super调用父类的方法,这样做即可以保有父类的功能,也可以拥有子类特有的功能
 *  方法重写的注意事项:
 *  			  不能重写父类私有的方法
 *  			 权限必须大于等于父类方法的权限
 *  
 *  注解:@
 *  
 */
public class ExtendsDemo5 {
	public static void main(String[] args) {
		NewPhone np = new NewPhone();
		np.call();
	}
}

//父类
class Phone {
	void call() {
		System.out.println("打电话");
	}
}

//子类
class NewPhone extends Phone {
	
	@Override // 说明方法是重写父类中的方法
	public void call() {
		System.out.println("录音");
		//System.out.println("打电话");
		
		//super.call();
	}
}

代码分析:首先创建一个父类——Phone,父类的方法是call,我们又创建一个子类,利用@Override对call方法进行重写,父类中函数类型是什么,子类中的函数类型必须是什么,;例如:父类中是Public,子类也必须是Public。

继承中的构造方法

  • 在对子类对象进行初始化时,父类的构造方法也会运行,那是因为子类的构造方法默认第一行有一条隐式的语句super()
  • super()会访问父类中的空参数构造方法。而且子类中所有的构造方法默认第一行都是super( )
package com.demo03;
/*
 * 继承中构造方法的执行顺序
 * 			在子父类中,创建子类对象,调用子类的构造方法,
 * 			在子类的构造方法的第一行代码如果没有调用父类的构造或者没有调用子类的其他构造,则默认调用父类无参构造
 * 为什么要调用父类构造?
 * 			因为需要给父类的成员变量初始化
 * 肯定会先把父类的构造执行完毕,再去执行子类构造中的其他代码
 * 
 * 我是父类无参构造 --- 我是子类有参构造 --- 我是子类无参构造
 */
public class ExtendsDemo6 {
	public static void main(String[] args) {
		//Parent d = new Parent();
		Son6 son = new Son6(1);
	}
}

class Parent6 {
	public Parent6() {
		System.out.println("我是父类无参构造");
	}
	
	public Parent6(int num) {
		System.out.println("我是父类有参构造");
	}
}

//子类
class Son6 extends Parent6 {
	public Son6() {
		super(1);//写不写一定会执行父类无参数
		System.out.println("我是子类无参构造");
	}
	
	public Son6(int num) {
		this(1l);
		//会默认调用父类无参构造
		System.out.println("我是子类有参构造");
	}
	
public Son6(long num) {
		//会默认调用父类无参构造
		System.out.println("我是子类有参构造");
	}
}

代码分析:在子类中不管写不写super(),都会执行父类无参构造,如果写super(1),将会执行父类有参构造,如果不想调用父类中的无参构造,我们应该写this(1),这样就不会调用父类中的无参构造了,但是最后子类Son6还是带调用了。这样一定会有一个子类方法去调用父类。他们之间不可以循环的调用。最终会导致子类中一定会有一个子类调用父类。

结果:

 super关键字 

  • super和this的用法相像
  • this代表对象的引用(谁调用就代表谁)
  • super代表当前子类对象父类的引用
  • 当子父类出现同名成员时,可以用super进行区
  • 子类要调用父类构造方法时,可以使用super语句

superthis的区别

  • this :对象的引用(谁调用就代表谁)
  • 使用this关键字引用成员变量。
  • 使用this关键字在自身构造方法内部引用其他构造方法。
  • 使用this关键字引用成员方法
  • super :当前对象里面的父类的引用。
  • 在子类的构造方法内部引用父类的构造方法。
  • 在子类中调用父类中的成员方法。
  • 在子类中调用父类中的成员变量。
package com.demo03;
/*
 * this和super的区别
		this:当前对象的引用
			调用子类的成员变量
			调用子类的成员方法
			在子类的构造方法第一行调用子类其他构造方法
		super:子类对象的父类引用
			调用父类的成员变量
			调用父类的成员方法
			在子类的构造方法第一行调用父类的构造方法
 */
public class ExtendsDemo7 {
	public static void main(String[] args) {
		Son z = new Son();
		z.function();
	}
}

//父类
class Parent {
	int num = 10;
	
	//无参构造方法
	public Parent() {
		System.out.println("我是父类无参构造");
	}
	// 有参构造方法
	public Parent(int num) {
		System.out.println("我是父类有参构造");
	}
	// 普通方法
	public void method() {
		System.out.println("我是父类的方法");
	}
}


// 子类
class Son extends Parent {
	int num = 30;
	
	public Son() {
		this(1);//第一行不调用子类其他构造或者是父类构造,默认调用父类无参构造
		//super();
		System.out.println("我是子类无参构造");
	}
	
	public Son(int num) {
		System.out.println("我是子类有参构造");
	}
	
	public void method() {
		System.out.println("我是子类的方法");
	}
	
	public void function() {
		//this.num = 50;
		//System.out.println(num);
		//this.method();
		
		//super.num = 40;
		super.method();
		
		//System.out.println(super.num);
		//System.out.println(this.num);
	}
}


代码分析:我们new了一个子类对象,看到this(1),子类的有参构造方法,但是里边没有super(),默认是父类的无参构造,再执行我是子类有参构造,执行完返回去,执行我是子类有参构造,构造方法执行完毕,再执行z.function。

结果显示:

继承的优缺点

  • 缺点:

        –类的耦合性增强了

        –开发的原则:高内聚低耦合

        –内聚:就是自己完成某件事情的能力

        –耦合:类与类的关系

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【自学Python】Python字符串以某个字符开始或结尾

大纲 Python字符串开头 Python字符串开头教程 在开发过程中,很多时候我们需要判断一个 字符串 是否以某个字符或者是否以某个字符串开始的需求,在 Python 中,判断某个字符串是否以某个字符或者是否以某个字符串开头的函数为 startswith() 。…

TFAPI使用2.0建议

2.5 TFAPI使用2.0建议 学习目标 目标 无应用 无 2.5.2 TF2.0最新架构图 饱受诟病TF1.0的API混乱 删除 queue runner 以支持 tf.data。删除图形集合。API 符号的移动和重命名。tf.contrib 将从核心 TensorFlow 存储库和构建过程中移除 TensorFlow 2.0 将专注于 简单性 和 易用…

【Unity VR开发】结合VRTK4.0:忽略某一层级

介绍: 由前面学习可知: 对象指针将与任何包含碰撞体(甚至是触发器碰撞体)的游戏对象发生冲突,但有时我们希望对象指针完全忽略游戏对象,就好像它不在场景中一样。 例如,如果我们手里拿着一个…

静图怎么做成gif动画图片?三步教你在线生成gif图片

说到gif动图相信大家都不陌生。那么,作为一名软件小白想要自己动手制作专属的gif动态图,要如何操作呢?接下来,给大家推荐一款专业在线gif制作(https://www.gif.cn/)工具-【GIF中文网】,通过两个…

力扣sql简单篇练习(七)

力扣sql简单篇练习(七) 1 销售分析 III 1.1 题目内容 1.1.1 基本题目信息1 1.1.2 基本题目信息2 1.1.3 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # 所查字段来自同一张表可优先考虑子查询,但需要考虑原表有,关联表没有的这种情况 SELECT p.product_id,p.produ…

GO基本知识学习(一)

文章目录 1 GO基本知识1.1 windows安装1.2 `Go Modules`依赖包查找机制1.3 变量定义1.4 创建一个go项目1.5`go`的变量类型1.6 go的变量初始化1.7 变量作用域1.8 注释1 GO基本知识 ​ 官网地址:https://www.golang.org/ ​ 国内下载地址:https://studygolang.com/dl 1.1 wi…

【springboot进阶】基于starter项目构建(二)构建starter项目-gson

这个系列讲解项目的构建方式,主要使用 父项目 parent 和 自定义 starter 结合。项目使用最新的 springboot3 和 jdk19。本系列的代码仓库看查看 gitee 仓库 的 starter 目录。 这篇我们开始学习创建属于自己的 starter ,实现一些常用模块的封装和自动配置…

Python | 数据类型之集合 | 函数

知识目录一、集合简介1.1 集合的定义1.2 实例二、集合的基本操作三、函数3.1 函数的定义3.2 函数的调用3.3 全局变量和局部变量一、集合简介 1.1 集合的定义 集合(set)是一个无序的不重复元素序列。 可以使用大括号 { } 或者 set() 函数创建集合&…

Hudi系列13:Hudi集成Hive

文章目录一. Hudi集成Hive概述二. Hudi集成Hive步骤2.1 拷贝jar包2.1.1 拷贝编译好的hudi的jar包2.1.2 拷贝Hive jar包到Flink lib目录2.1.3 Flink以及Flink SQL连接Hive的jar包2.2 重启hive2.3 Flink访问Hive表2.3.1 启动Flink SQL Client2.3.2 创建hive catalog2.3.3 切换 ca…

cpanel面板的虚拟主机重装wordpress

cpanel面板的虚拟主机重装wordpress很多朋友购买的虚拟主机都是采用的cPanel面板。想要重装WordPress的话,跟着以下步骤操作即可。登录cPanel管理后台,进入文件管理;删除网站的所有文件(如果有需要请先备份然后下载到本地&#xf…

Ubuntu18.04 gRPC编译安装

一、CMake版本检查 grpc编译cmake要求最低版本为3.15。首先,cmake -version 查看当前cmake版本,如果低于3.15,按照以下步骤进行安装。 1.1 卸载已经安装的旧版的CMake sudo apt-get autoremove cmake 1.2 下载最新版本CMake CMake下载地…

2023年湖北中级工程师职称怎么评?甘建二告诉你

春季开始了,又到了职称评审正式申报提交资料的时候了,很多想评职称的小伙伴都不知道中级职称要怎么评?需要本人提供什么资料?配合哪些事情?怎么评一个中级职称呢?接下来甘建二老师跟您一起来看看&#xff1…

Redis性能问题排查指引

目录 Redis性能问题排查手段 1. 定位问题点 2. 定位Redis具体性能问题 参考: Redis性能问题排查手段 1. 定位问题点 当发生业务系统访问Redis慢或者超时异常时,可能的原因有以下三个: 客户端问题: 如果客户端使用的是Java版…

VueJS 之组件的生命周期

文章目录参考描述生命周期生命周期图示生命周期钩子组件创建阶段组件运行阶段组件销毁阶段举个栗子参考 项目描述搜索引擎Bing哔哩哔哩黑马程序员VueJS官方文档 描述 项目描述Edge109.0.1518.70 (正式版本) (64 位)操作系统Windows 10 专业版vue/cli5.0.8npm8.19.3VueJS2.6.1…

实战30:基于Open CV的车道线检测 附完整代码

车道线检测,在色彩切片、边界提取处,可以选用许多不同的方法来实现。色彩切片处是希望通过车道线的颜色特征:白色或者黄色来提取车道线,白色和黄色单独提取后两者图像相加便得到了同时含有白色车道和黄色车道的图像。色彩切片步骤的关键在于如何获得较为纯净的车道线,以让…

Java JVM:Java 内存模型与线程(七)

衡量一个服务性能的高低好坏,每秒事物处理数(TPS)是重要的指标之一,而 TPS 值与程序的并发能力又有非常密切的关系 目录一、硬件的效率与一致性二、Java 内存模型三、Java 与线程这里是看书笔记,之前文章也有相关介绍&…

操作系统权限提升(八)之系统错误配置-注册表键AlwaysInstall提权

系列文章 操作系统权限提升(一)之操作系统权限介绍 操作系统权限提升(二)之常见提权的环境介绍 操作系统权限提升(三)之Windows系统内核溢出漏洞提权 操作系统权限提升(四)之系统错误配置-Tusted Service Paths提权 操作系统权限提升(五)之系统错误配置-PATH环境变量提权 操作…

异质性区域下的宏观基本图构建

这是我们发表在Physica A: Statistical Mechanics and its Applications期刊上的一篇论文,主要是对现在的宏观基本图构建进行了一定的优化,论文详见:https://www.sciencedirect.com/science/article/pii/S0378437123000869 1.论文概述 论文…

stream操作常用API 示例详解

简介 从JDK8开始,增加了一新特性Stream流式操作,Stream中提供了非常多的API供大家使用,灵活的使用这些API,可以非常的方便且优美的实现我们的代码逻辑。 流式操作主要用来处理数据(比如集合),…

Java两大工具库:Commons和Guava(4)

您好,我是湘王,这是我的CSDN博客。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!在Nginx中提到过…