今日内容
继承
this和super关键字
抽象类
继承(extends)
现实世界中的继承是儿子拥有父辈的财产
在Java中的继承是子类拥有父类的“内容”
描述的是一种所属关系,"is a"的关系
子类拥有父类的“内容”
内容:
非private修饰的成员变量
非private修饰的成员方法
注意:
(1)构造方法不能被继承
(2)私有的成员变量和成员方法不能被继承
继承的由来
多个类的共性内容不断向上抽取,得到的类就是父类,这多个类就可以称为子类
继承的格式:
public class 子类 extends 父类 {
}
继承的好处:
(1)提供了代码的复用性
(2)继承是多态的前提之一
继承中成员变量访问的特点
(1)继承之后,只可能子类拥有父类的内容,但是不可能父类去拥有子类的内容
(2)就近原则,子类中如果有则使用子类的,如果子类中没有则使用父类的
(3)如果是通过成员方法间接访问,对象是谁我就找谁,如果没有再往上找
局部变量、本类的成员变量和父类的成员变量重名情况下的访问
(1)就近原则,谁离我近我就使用谁
如果有局部变量,就使用局部变量,
如果没有局部变量,就找本类的成员变量,
如果本类的成员变量没有,就找父类的成员变量
如果父类的成员变量也没有,报错
(2)如果局部变量、本类的成员变量和父类的成员变量都有
如果想访问局部变量,直接访问
如果想访问本类的成员变量,通过this.的方式访问
如果想访问父类的成员变量,通过super.的方式访问
继承中成员方法访问的特点:
就近原则,谁离我近我就使用谁
子类有该方法,创建子类对象使用的是子类的方法,
如果子类没有该方法,则向上找父类的方法
如果父类也没有该方法,则报错
方法重写(覆盖)
什么是方法重写
在继承关系中(子父类),子类和父类中的方法声明(一般)一致,但是方法体进行重新定义的过程
为什么要方法重写(使用场景)
继承之后,父类的方法无法满足子类对于功能的需求
方法重写的条件(注意事项)
方法重写一般都是子类的方法声明和父类完全一致,但是如果偏要声明不一致,则需要满足以下条件:
一大两同两小
一大:子类重写的方法的权限修饰符必须大于等于父类方法的权限修饰符
权限修饰符:public > protected > 默认 > private
以下属于的权限修饰符的是 a
a.private
b.static
c.default
d.void
两同:
子类重写的方法必须和父类的方法名完全相同
子类重写的方法的参数列表必须和父类的方法参数列表完全相同
两小:
子类重写的方法的返回值类型必须小于等于父类方法的返回值类型(针对的只是引用数据类型,对基本数据无效)
如果返回值类型是基本数据类型或者是void,那么子类必须一样
如果返回值类型是引用数据类型,满足小于等于就可以,引用数据类型大小:父类 > 子类
子类重写方法抛出的异常必须小于等于父类的异常,或者少于等于父类的异常,
如果父类没有抛出异常,子类方法必须不能有异常
面试题:方法重写和方法重载的区别
方法重载(Overload)
(1)在同一个类中
(2)方法名相同,参数列表不同
(3)和其他(权限修饰符、返回值类型、抛出的异常)的无关
方法重写(Override)
(1)在多个类(有继承关系的子父类)中
(2)方法名相同,参数列表相同
(3)和其他(权限修饰符、返回值类型、抛出的异常)的有关
如果不同需满足以上的条件
继承中,父子类构造方法访问的特点:
父类构造方法一定会先于子类构造方法执行。
(1)每一个构造方法的第一行语句默认都有一个super(),调用的是父类的无参构造方法
(2)如果显式在构造方法中使用super(参数)和this(参数),这样的语句调用父类的构造方法或者本类的其他构造方法,
那么默认的super()就没有了。
super(参数)和this(参数)必须位于构造方法的第一行来调用,而且它们在同一个构造方法中不能同时出现
super(参数)和this(参数)只能在构造方法中使用,不能在其他地方使用
this和super的区别
this:代表当前对象的引用,谁来调用方法谁就代表当前对象
(1)可以调用本类的成员变量,通过this.成员变量
(2)可以调用本类的成员方法,通过this.成员方法
(3)可以在本类的构造方法中的调用本类的其他构造方法,通过this(参数)的方式
super:代表父类的那片空间,通过它可以访问父类的内容
(1)可以在本类成员方法中调用父类的成员变量,通过super.成员变量
(2)可以在本类成员方法中调用父类的成员方法,通过super.成员方法
(3)可以在本类的构造方法中调用父类的构造方法,通过super(参数)的方式
继承中的三个特点:
(1)Java语言中的类是单继承的,不支持多继承
也就是一个类只能有一个直接父类,不能有多个直接父类
class A{}
class B{}
class C extends A,B{} // 错误的,这是多继承,不支持
(2)Java语言中的类可以多层继承
多层继承,一个类不光可以继承父类中的内容,还可以继承爷爷类中内容
class A{}
class B extends A{}
class C extends B{} // 正确的,这是多层继承,支持
(3)Java语言中一个类可以是多个类的父类
class A{}
class B extends A{}
class C extends A{} // 正确的,A同时是B和C的父类,支持
面试题:Java语言是单继承的吗?
如果是类,是单继承的
如果是接口,可以单继承也可以多继承
抽象(abstract)类
抽象:反义词是具体,不清楚不确定
抽象的由来
多个类不断向上抽取,在多个类中的功能是具体是明确的,但是抽取到父类中之后该功能就不明确了
例如:一个三角形计算面积可以具体实现,一个圆形计算面积也可以具体实现,它们两个都有计算面积的方法
这时共性内容不断向上抽取,形成一个父类,父类中的计算面积的方法就无法明确如何实现,这是这个方法就应该
定义为抽象的方法。
抽象类:使用abstract关键字修饰的类
如果一个类中有抽象方法,那么这个类必须是抽象类
格式:
// 抽象类
public abstract class 类名 {
// 抽象方法
public abstract 返回值类型 方法名(参数列表);
}
抽象类的特点:
(1)抽象类和抽象方法都必须使用abstract关键字修饰
(2)不能创建对象
(3)一个类去继承抽象类,要么实现所有的抽象方法
要么该类必须也是一个抽象类
(4)抽象类有构造方法
构造方法两个作用:
a:创建对象
b:给成员变量初始化
(5)类与抽象类之间的关系是继承
(6)抽象类中可以有抽象方法也可以没有抽象方法
抽象类中可以非抽象的方法
课堂案例一:
分析以下需求,并用代码实现
老师类:
属性:姓名,年龄,性别
行为:讲课,吃饭
基础班老师:
属性:姓名,年龄,性别
行为:讲基础班课程,吃饭
就业班老师:
属性:姓名,年龄,性别
行为:讲就业班课程,吃饭
定义测试类:
分别创建基础班老师对象和就业班老师对象
调用各自的讲课方法
要求:
分析各个事物之间的继承关系,抽取出相关的类
课堂案例二:
分析以下需求,并用代码实现
1.定义员工类:
属性:
工号,姓名
行为:
工作方法
2.定义经理类:
属性:
工号,姓名,奖金
行为:
工作方法(管理员工,简单输出语句模拟)
3.定义服务员类:
属性:
工号,姓名
行为:
工作方法(为客户服务,简单输出语句模拟)
4.定义测试类:
分别创建经理类对象和服务员类对象
调用各自的工作方法
要求:
分析各个事物之间的继承关系,抽取出相关的类