day09 继承、super、this、抽象类
day09 继承、super、this、抽象类
2020年2月18日
目录
1 继承
1.1 概述
多个类中存在相同属性和行为时,将这些内容抽取到单独的类中,那么多个类不需要再定义这些属性和行为,只要继承那个类即可。
多个类可称为子类,单独的一个类可称为父类、超类(superclass)、基类
- 继承:就是子类继承父类的属性和行为,使得子类具有与父类相同的属性、行为,子类可以直接访问父类中非私有的属性和行为。
继承的好处:
- 提高代码的复用性
- 多态的前提
1.2 继承的格式
通过extends
关键字声明一个子类继承另外一个父类
//定义一个父类:员工
public class Employee {
public void method(){
System.out.println("方法执行");
}
}
//定义了一个员工的子类:讲师
public class Teacher extends Employee {
}
1.3 继承后的特点——成员变量
- 成员变量不重名,无影响
- 成员变量重名,子类中需要访问父类中非私有成员变量时,需要使用
super
关键字修饰父类成员变量
/*
在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:
直接通过子类对象访问成员变量:
等号左边是谁,就优先用谁,没有则向上找
间接通过成员方法访问成员变量:
该方法属于谁,就优先用谁,没有则向上找
*/
public class Demo01ExtendsField {
public static void main(String[] args) {
Fu fu=new Fu();
System.out.println(fu.numFu);//只能使用父类的东西,没有任何子类内存
Zi zi=new Zi();
System.out.println(zi.numFu);
System.out.println(zi.numZi);
//等号左边是谁,就优先用谁
System.out.println(zi.num);
//这个方法是子类的,优先用子类的,没有再向上找
zi.methodZi();//200
//这个方法是在父类当中,属于父类,输出的是父类的100
zi.methodFu();//100
}
}
父类中成员变量私有后,子类不能直接访问。通常在编码的时候,我们遵循封装的原则,用private修饰成员变量,在父类中提供公共的getXxx和setXxx方法。
1.4 继承后的特点——成员方法
- 成员变量不重名:对象调用方法时,首先会在子类查找有没有对应的方法,若子类中存在就会执行子类中的方法,若不存在就会执行父类的方法
- 成员变量重名——重写(override)
- 方法重写:子类中出现与父类一模一样的方法时(返回值类型、参数列表、方法名都相同),会出现覆盖效果,也称为重写或复写,声明不变,重新实现。
- 重写的应用:子类可以根据需要,定义特定于自己的行为,既沿袭了父类的功能名称,又根据子类的需要重新实现了父类方法,从而进行扩展增强。
重写时用到super.父类方法,表示调用父类的成员方法
/*
在父子类的继承关系中,创建子类对象,访问成员方法的规则:
创建的对象是谁,则优先用谁,如果没有则向上找
注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的
重写(override)
概念:在继承关系中,方法的名称一样,参数列表也一样
重写(override):方法的名称一样,参数列表【也一样】。覆盖、覆写
重载(overload):方法的名称一样,参数列表【不一样】
方法的覆盖重写特点:创建的是子类对象,则优先用子类方法
*/
public class Fu {
public void methodFu(){
System.out.println("父类方法执行");
}
public void method(){
System.out.println("父类重名方法执行");
}
}
public class Zi extends Fu {
public void methodZi(){
System.out.println("子类方法执行");
}
public void method(){
super.method();
System.out.println("子类重名方法执行");
}
}
注意事项
- 子类方法覆盖父类方法,必须保证权限大于父类权限
- 子类方法覆盖父类方法,返回值类型、函数名、参数列表都要一模一样
1.5 继承后的特点——构造方法
关于构造方法:
- 构造方法的名字与类名一致,所以子类无法继承父类的构造方法
- 构造方法的作用是初始化成员变量,所以子类初始化的过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个
super()
,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
/*
继承关系中,父子类构造方法的访问特点:
1.子类构造方法中有一个默认隐含的“super()”调用,所以一定是先调用父类构造,后执行子类构造。
2.子类构造可以通过super关键字来调用父类重载构造
3.super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多次super构造
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用指定的super调用,super只能有一个,还必须是第一个
*/
public class Fu {
public Fu(int num){
System.out.println("父类构造方法");
}
}
public class Zi extends Fu {
public Zi(){
super(20);
// super();
System.out.println("子类构造方法");
}
public void method(){
// super();//错误写法!只有子类构造方法,才能调用父类构造方法
}
}
1.6 super和this
父类空间优于子类对象产生
每次创建子类对象时,先初始化父类空间,再创造子类对象本身,目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员。如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类构造方法调用时,一定要先调用父类的构造方法
super和this的含义
- super:代表父类的存储空间标识(可理解为父类的引用)
- this:代表当前对象的引用(谁调用就代表谁)
super和this的用法
- 访问成员
- 访问构造方法
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖掉默认的super()。super()和this()都必须在构造方法的第一行,所以不能同时出现
2 抽象类
2.1 概述
没有方法主体的方法称为抽象方法,包含抽象方法的类就是抽象类
2.2 abstract使用格式
用abstract
关键字修饰方法,抽象方法只包含一个方法名,没有方法体
抽象的使用
继承抽象类的子类必须重写父类所有的抽象方法,否则该子类也必须声明为抽象类。
此时的方法重写,是子类对父类抽象方法的实现,这种将方法重写的操作,也叫做实现方法
2.3 注意事项
- 抽象类不能创建对象
- 抽象类可以有构造方法,是供子类创建对象时,初始化父类成员使用的
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必然是抽象类
- 抽象类的子类必须重写抽象父类中的抽象方法