第五章:面向对象(中)
5.1继承
**继承:**从现有类创建子类, 现有类称为父类(先有父类才有子类), 基类(子类是父类的扩展), 超类(子类中使用了super)
注意:
- 子类继承父类的所有成员 (构造器除外)
- 子类可以继承父类的私有成员,但是不可直接访问
- Java中只支持单继承,也就是所只能有一个直接父类
5.2方法的重写
**重写:**子类继承父类之后,可以对父类中同名同参数的方法,进行覆盖操作
/*方法的声明:权限修饰符 返回值类型 方法名(形参列表) throws 异常类型{
方法体;
}
*/
**应用:**重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法
重写的规定:
- 子类重写的方法的方法名和形参列表与父类中被重写的方法的方法名和形参列表相同
- 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符(其中父类若为private,则不能被重写)
- 返回值类型
- 父类重写的方法的返回值类型是void,则子类重写的方法的返回值只能是void
- 父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
- 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
5.3 关键字:this
使用含义:
- 在方法内部使用,即调用该方法的调用者对象
- 在构造器内部使用,表示该构造器正在初始化的对象
5.4 关键字:super
super用法:
- 访问父类中定义的属性
- 调用父类中定义的成员方法
- 用于在子类构造方法中调用父类的构造器
注意:
- 尤其当子父类出现同名成员时,可以用super进行区分
- super的追溯不仅限于直接父类
- super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
No. | 区别 | This | super |
---|---|---|---|
1 | 访问属性 | 访问本类中的属性,如果没有则在父类中查找 | 访问父类中的属性 |
2 | 调用方法 | 访问本类中的属性,如果没有则在父类中查找 | 直接调用父类中的方法 |
3 | 调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用直接父类构造器,必须放在子类构造器的首行 |
4 | 特殊 | 表示当前对象 | 无此概念 |
5.5多态
多态性的体现:
- 对象的多态性
- 引用变量的多态性
对象的多态性 —> 子类对象的多种父类形态
引用变量的多态性—>一个引用类型变量可能指向(引用)多种不同类型的对象
对象方法具备多态性:编译时看父类,运行时看子类
成员变量不具备多态性,原因是它没有覆盖,编译和运行总是一致
多态注意点:
- 造型有风险,必须加判断
- 造型时,对象类型的判断一定是从最子类到最父类
- 副作用:子类的特殊成员不可访问
多态参数的好处:可以接受任意本类及子类对象
多态数组的好处:可以保存任意本类及子类的对象
多态小结:
- 有继承
- 有覆盖(重写)
引用变量的多态性:
- 一个基本型变量只能有一种确定的数据类型
- 一个引用类型变量可能指向(引用)多种不同类型的对象
子类可看做是特殊的父类,所以父类类型的引用可以指向子 类的对象:向上转型
**多态副作用:**一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
虚拟方法调用 : 通过多态引用调用覆盖方法.
- 编译时检查父类类型
- 运行时动态绑定具体new的子类对象
定义:子类中重写了父类中同名同参的方法,在多态情况下,父类此时的方法成为虚拟方法,父类根据赋给它的不同子类对象,动态调用 属于子类的该方法,这样的方法调用在编译期是无法确定的
引用变量的类型:
- 编译时类型
- 运行时类型 -------动态绑定
5.6四种访问权限修饰符
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
5.7 object类
**object类:**所有类的根父类
如果在类的声明中未使用extends指明其父类,则默认父类为object类
- equals:判断当前this对象的内容和参数中的对象的内容是否相等
- hashCode:返回当前对象的哈希码
- toString:对象打印时调用
== 和 equals的区别:
- == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
- equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点
- 具体要看自定义类里有没有重写Object的equals方法来判断
- 通常情况下,重写equals方法,会比较类中的相应属性是否都相等
哈希码:
- 散列码
- 特征码
5.8 对象类型转换
- 从子类到父类的类型可以自动进行
- 从父类到子类的类型转换必须通过造型实现
- 无继承关系的引用类型间的转换是非法的
- 在造型前可以使用instanceof 进行对象类型的判断
5.9 intanceof操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型
- 要求x所属的类与类A必须是子类和父类的关系,否则编译错误
- 如果x属于类A的子类B,x instanceof A 的值也为true
**使用情境:**为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型;如果返回false,就终止向下转型
5.10 单元测试类的使用
Java中的JUnit单元测试步骤:
- 选中当前工程,右键选择:build path - add libraries - JUnit4 ,点击下一步
- 创建Java类,进行单元测试,要求:①此类是公共的 ②此类要提供一个公共的无参构造器
- 在此类中声明单元测试方法,要求:①方法的权限是public ②没有返回值 ③没有形参
- 此单元测试方法上需要声明@Test,并导入测试类的包
- 声明好单元测试方法以后,就可以在方法体内测试相关代码
- 写完代码以后,左键双击方法名,右键 run as -JUnit
5.11 包装类的使用
**包装类(封装类):**针对八种数据类型定义相应的引用类型
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Booolean |
char | Character |
基本数据类型、包装类、和String的相互转化:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6YUlTVsb-1662774208125)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220907234931827.png)]
JDK5新特性:自动装箱与自动拆箱
基本数据类型转换为包装类:
1.调用包装类的构造器
包装类转换成基本数据类型:
1.调用包装类的xxxValue()
基本数据类型与包装类转换成String类型:
1.调用String重载的ValueOf(xxx)
2.拼接:“” + xxx
String类型转换成基本数据类型和包装类:
1.调用包装类的parsexxx()方法