学习JavaEE的日子 day14 继承,super(),this(),重写

Day14

1.继承的使用

理解:子类继承父类所有的属性和方法
使用场景:多个类似的类,有相同的属性和方法,就可以把相同属性和方法抽取到父类
优点:减少代码的冗余; 使类与类之间产生了关系(多态的前提)
缺点:继承会增加类与类之间的关系,会增加代码的维护难度
需求:编写中国人和日本人的类,创建各自的对象

分析:

复制代码
  人类:

  	属性:姓名、性别、年龄

  	方法:吃饭饭、睡觉觉

  中国人的类 继承 人类 :

  	属性:身份证

  	方法:打太极

  日本人的类 继承 人类:

  	属性:年号

​ 方法:拍电影

java 复制代码
//父类
public class Person {
	
	String name;
	char sex;
	int age;
	
	public void eat(){
		System.out.println(this.name + "吃饭饭");
	}
	
	public void sleep(){
		System.out.println(this.name + "睡觉觉");
	}
}
java 复制代码
//            子类           继承        父类
public class Chinese extends Person{

	String id;
	
	public void playTaiJi(){
		System.out.println("中国人打太极");
	}
}
java 复制代码
//			     子类           继承        父类
public class Japanese extends Person{

	String yearNum;
	
	public void playVideo(){
		System.out.println("日本人拍电影");
	}
}
java 复制代码
//测试类
public class Test01 {
	public static void main(String[] args) {
		
		//创建对象
		Chinese c = new Chinese();
		
		//操作父类属性
		c.name = "小彭";
		c.sex = '男';
		c.age = 21;
		
		//操作子类属性
		c.id = "1234567890";
		
		//调用父类方法
		c.eat();
		c.sleep();
		
		//调用子类方法
		c.playTaiJi();
		
		System.out.println("-----------------------------");
		
		//创建对象
		Japanese j = new Japanese();
		
		//操作父类属性
		j.name = "波多野结衣";
		j.sex = '女';
		j.age = 18;
		
		//操作子类属性
		j.yearNum = "令和";
		
		//调用父类方法
		j.eat();
		j.sleep();
		
		//调用子类方法
		j.playVideo();
		
	}
}

继承内存图:

父类空间优先于子类对象产生

在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法

小结

1.继承实际上是子类相同的属性和行为可以定义在父类中,子类特有的属性和行为由自己定义,这样就实现了相同属性和行为的重复利用,从而提高了代码复用。

2.继承是在多个类中之间的,使用关键字extends,在父类的非私有属性和方法可以被子类继承

3.java是单继承的

2.继承的深入

面试题

1.创建子类对象,会调用父类的构造方法吗?


2.创建子类对象,为什么会调用父类构造方法?

因为会在子类对象中开辟空间,用于存储父类的成员属性
3.创建子类对象,先调用父类构造方法还是子类构造方法?

先调用子类的构造方法
4.创建子类对象,先完成父类构造方法还是子类构造方法?

先完成父类的构造方法
5.子类对象是否能继承父类所有的属性和方法?

Java官网上,明确表示子类不能继承父类私有化的属性和方法,这是站在使用的角度

实际上,子类能继承父类私有化的属性方法,但是不能直接使用,可以在父类中编写公有方法去调用私有的属性和方法

*值得注意的是子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问而已,可以通过在父类中设置get/set方法访问父类的private成员变量。*

java 复制代码
public class Father {
private String fatherAttr = "父类私有化属性";

public Father() {
	System.out.println("调用父类的构造方法");
}

public String getFatherAttr() {
	return fatherAttr;
}

public void setFatherAttr(String fatherAttr) {
	this.fatherAttr = fatherAttr;
}

private void method01(){
	System.out.println("父类私有化方法");
}

public void method02(){
	method01();
}
}
java 复制代码
public class Son extends Father{

	public Son() {
		//super();//默认实现:调用父类的构造方法,所以首先完成父类构造方法,再执行下一句
		System.out.println("调用子类的构造方法");
	}
}
java 复制代码
//测试类
public class Test01 {
  public static void main(String[] args) {
	
	Son son = new Son();
	
	System.out.println(son.getFatherAttr());
	
	son.method02();
  }
}

3.super

理解:super表示父类

super代表的是父类对象的引用,this代表的是当前对象的引用。*
作用:

1.super.属性:在子类中,调用父类的非私有化的成员属性(不常用,因为属性已经私有化了)

2.super.方法:在子类中,调用父类的非私有化的成员方法

3.super():在子类构造方法中的第一句调用父类的非私有化的构造方法
需求:编写中国人和日本人的类,创建各自的对象

java 复制代码
public class Person {
	
	private String name;
	
	public Person() {
	}
	
	public Person(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void eat(){
		System.out.println(this.name + "吃饭饭");//name这个属性是本类的,所以使用this,而不是super
	}
}
java 复制代码
public class Chinese extends Person{

	private String id;
	
	public Chinese() {
	}
	
	public Chinese(String name,String id) {
		super(name);//子类中把父类的成员变量一起有参构造出来,方便使用
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void playTaiJi(){
		
		System.out.println(super.getName() + "打太极");//super.属性:用的是分类的成员变量,子类中没有名字这个属性
	}
}
java 复制代码
public class Japanese extends Person{

	private String yearNum;
	
	public Japanese() {
	}
	
	public Japanese(String name,String yearNum) {
		super(name);
		this.yearNum = yearNum;
	}

	public String getYearNum() {
		return yearNum;
	}

	public void setYearNum(String yearNum) {
		this.yearNum = yearNum;
	}

	public void playVideo(){
		System.out.println(super.getName() + "拍电影");//super.属性:用的是分类的成员变量,子类中没有名字这个属性
	}
}
java 复制代码
public class Test01 {
	public static void main(String[] args) {
	
	//创建对象
	Chinese c = new Chinese("小彭", "1234567890");
	
	//调用父类方法
	c.eat();
	
	//调用子类方法
	c.playTaiJi();
	
	System.out.println("-----------------------------");
	
	//创建对象
	Japanese j = new Japanese("波多野结衣",  "令和");
	
	//调用父类方法
	j.eat();
	
	//调用子类方法
	j.playVideo();
	
}
}

小结 - 编写一个类的步骤:

1.属性

2.私有化属性

3.无参构造

4.有参构造

5.get/set方法

6.其他的方法

3.1 继承后的特点------构造方法

构造方法的名字是与类名一致的。

构造方法的作用是初始化对象成员变量数据的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。(*先有爸爸,才能有儿子*
*继承后子类构方法器特点:子类所有构造方法的第一行都会默认先调用父类的无参构造方法*****
子类构造方法的第一行都隐含了一个super()调用父类无参数构造方法,super()可以省略不写。

3.2 super和this的用法格式

this.成员变量 -- 本类的

this.成员方法名() -- 本类的
super.成员变量 -- 父类的

super.成员方法名() -- 父类的
接下来我们使用调用构造方法格式:

this(...) -- 调用本类的其他构造方法,根据参数匹配确认

super(...) -- 调用父类的构造方法,根据参数匹配确认
注意:

*子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。*

*super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。*

4.重写/复写

理解:在子类中,将父类的方法重新写一遍

子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。*声明不变,重新实现*
应用场景:父类方法不能被改动时,在子类中重新写一遍
条件:

1.在子类中重写父类的方法

2.返回值、方法名、参数列表必须跟父类重写的方法一致

3.访问修饰符不能比父类更严格
面试题:重写(overriding)与重载(overloading)的区别?

重写是发生在子父类继承关系中方法名相同,参数列表相同,返回值相同,子类访问修饰符要大于等于父类的修饰符,子类的异常声明必须小于等于父类的异常声明;

方法重载发生在同一个类中,方法名相同,参数列表不同,返回值无关。
需求:编写中国人和日本人的类,创建各自的对象

java 复制代码
public class Test01 {	
	public static void main(String[] args) {
	//创建对象
	Chinese c = new Chinese("小彭", "1234567890");
	
	c.eat();//调用子类重写后的方法
	
	System.out.println("-----------------------------");
	
	//创建对象
	Japanese j = new Japanese("波多野结衣","令和");
	
	j.eat();//调用子类重写后的方法
	
}
}
java 复制代码
public class Person {
	
	private String name;
	
	public Person() {
	}
	
	public Person(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void eat(){
		System.out.println(this.name + "吃饭饭");
	}
}
java 复制代码
public class Chinese extends Person{

	private String id;
	
	public Chinese() {
	}
	
	public Chinese(String name, String id) {
		super(name);
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	
	//@Override -- 重写的注解
	//注解:给程序员和系统解释代码信息
	@Override
	public void eat(){
		System.out.println(super.getName() + "吃山珍海味");
	}
}
java 复制代码
public class Japanese extends Person{

	private String yearNum;
	
	public Japanese() {
	}
	
	public Japanese(String name,String yearNum) {
		super(name);
		this.yearNum = yearNum;
	}

	public String getYearNum() {
		return yearNum;
	}

	public void setYearNum(String yearNum) {
		this.yearNum = yearNum;
	}

	@Override
	public void eat() {
		System.out.println(super.getName() + "吃生鱼片");
	}
}

4.1 @Override重写注解

@Override:注解,重写注解校验!

这个注解标记的方法,就说明这个方法必须是重写父类的方法,否则编译阶段报错。

建议重写都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!

4.2 注意事项

1.方法重写是发生在子父类之间的关系。

2.子类方法覆盖父类方法,必须要保证权限大于等于父类权限。

3.子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。

4.父类中的方法使用private,static,final任意修饰符,那么,不能被子类重写。

5.总结

1.继承的使用

2.继承的深入 --- 重要

3.super

4.重写

相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习