目录
一、课程目标
二、方法重写
1. 为什么要学习方法重写
2. 什么是方法重写
3. 方法重写规则
4. 方法重写vs方法重载
5. 练习:使用重写优化电子宠物系统
三、Object类
1. 基本概念
2. Object类被子类经常重写的方法
3. Object类的equals()方法
4. 练习:重写equals()
四、多态
1. 为什么使用多态
2. 什么是多态
3. 多态的使用
4. 抽象类与抽象方法
5. 练习:使用多态实现为宠物喂食
五、转型
1. 向上转型
2. 向下转型
六、instanceof运算符
练习:使用多态实现主人领养宠物并与宠物玩耍功能
七、多态的应用
练习:打印商品价格
八、总结要点
一、课程目标
学完本次课程后,能够达成以下目标:
-
实现方法重写
-
深入理解继承相关概念
-
了解Object类
-
会使用重写实现多态机制
-
会使用instanceof运算符
-
会使用向上转型
-
会使用向下转型
二、方法重写
1. 为什么要学习方法重写
在继承实现的电子宠物系统中,调用父类的print()方法,不能显示Dog的strain信息和Peguin的sex信息,而方法重写可以解决这一问题,让子类根据自身需求展示特定信息。
2. 什么是方法重写
方法的重写或方法的覆盖(overriding),指子类根据需求对从父类继承的方法进行重新编写。重写时,可以用super.方法的方式来保留父类的方法。需要注意的是,构造方法不能被重写。
3. 方法重写规则
-
方法名相同
-
参数列表相同
-
返回值类型相同或者是其子类
-
访问权限不能严于父类
-
父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
-
子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
-
父类的私有方法不能被子类覆盖
-
不能抛出比父类方法更多的异常
4. 方法重写vs方法重载
方法重写 | 子类 | 相同 | 相同 | 相同或是其子类 | 不能比父类更严格 |
方法重载 | 同类 | 相同 | 不相同 | 无关 | 无关 |
5. 练习:使用重写优化电子宠物系统
需求说明:使用方法重写优化电子宠物系统,使Dog和Penguin在输出自白时能分别显示strain信息和sex信息,如:
宠物的自白:
我的名字叫欧欧,我的健康值是100,我和主人的亲密程度是0。
我是一只雪娜瑞犬。
宠物的自白:
我的名字叫楠楠,我的健康值是100,我和主人的亲密程度是0。
我的性别是Q妹。
三、Object类
1. 基本概念
Object类是所有类的父类,任何类都默认继承Object类,如public class Pet extends Object {……} 。
2. Object类被子类经常重写的方法
toString() | 返回当前对象本身的有关信息,按字符串对象返回 |
equals() | 比较两个对象是否是同一个对象,是则返回true |
hashCode() | 返回该对象的哈希代码值 |
getClass() | 获取当前对象所属的类信息,返回Class对象 |
3. Object类的equals()方法
-
比较两个对象是否是同一个对象,是则返回true。
-
与操作符==的区别:
-
简单数据类型,==直接比较值,如1==2。
-
引用类型,==比较两者是否为同一对象。
-
-
相关说明: (1)Object类的equals()方法与==没区别。 (2)当有特殊需求,如认为属性相同即为同一对象时,需要重写equals()。 (3)Java.lang.String重写了equals()方法,把equals()方法的判断变为了判断其值。
4. 练习:重写equals()
需求说明:重写比较规则,判断两名学员(Student)是否为同一对象。Student相关属性有Id(学号)、name(姓名)、age(年龄),如果两名学员的学号以及姓名相同,则为同一对象。
四、多态
1. 为什么使用多态
在之前的电子宠物系统中,主人类给不同宠物看病需要编写不同的方法,如给企鹅看病、给狗看病。当需要给新的宠物看病时,需要频繁修改代码,添加新的类和方法,导致代码可扩展性、可维护性差。而多态可以解决这一问题。
2. 什么是多态
多态指同一个引用类型,使用不同的实例而执行不同操作,即同一种事物,由于条件不同,产生的结果也不同。比如不同类型的打印机打印效果不同。
3. 多态的使用
-
使用多态优化后的代码示例:
//Dog类
public class Dog extends Pet {
public void toHospital() {
this.setHealth(60);
System.out.println("打针、吃药");
}
}
//Penguin类
public class Penguin extends Pet {
public void toHospital() {
this.setHealth(70);
System.out.println("吃药、疗养");
}
}
//主人类
public class Master {
public void cure(Pet pet) {
if (pet.getHealth() < 50)
pet.toHospital();
}
}
//测试方法
Pet pet = new Dog();
Master master = new Master();
master.cure(pet); -
当又要给新的宠物看病时,只需编写新的类继承Pet类并创建对象,其他代码无需修改(不用修改Master类)。
-
方法重写是实现多态的基础。
4. 抽象类与抽象方法
-
问题:Pet类的toHospital()不需要有具体的实现,实例化Pet毫无意义。
-
抽象方法:没有方法体,必须在抽象类里,且必须在子类中被实现,除非子类是抽象类,如public abstract void print();。
-
抽象类:包含抽象方法的类,声明为public abstract class Pet {……} 。
5. 练习:使用多态实现为宠物喂食
需求说明:宠物饿了,主人需要为宠物喂食,使用多态实现该过程。不同宠物吃的东西不一样,吃完东西后恢复健康值也不一样,狗狗健康值增加3,企鹅健康值增加5,且健康值达到100时,不需要继续喂食。
五、转型
1. 向上转型
-
概念:父类的引用指向子类对象,自动进行类型转换,格式为<父类型> <引用变量名> = new <子类型>();。
-
注意:此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法,且无法调用子类特有的方法。
-
示例:
//测试方法
Pet pet = new Dog();
pet.setHealth(20);
Master master = new Master();
master.cure(pet);
2. 向下转型
-
概念:将一个指向子类对象的父类引用赋给一个子类的引用,即父类类型转换为子类类型,需要强制类型转换,格式为<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;。
-
注意:在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常。
-
示例:
Dog dog=(Dog)pet;//将pet 转换为Dog类型
dog.catchingFlyDisc();//执行Dog特有的方法
六、instanceof运算符
-
作用:用于判断一个引用类型所引用的对象是否是一个类的实例。
-
注意:使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系。
-
应用:可以减少在向下转型过程中因没有转换为真实子类类型而出现的类型转换异常。
练习:使用多态实现主人领养宠物并与宠物玩耍功能
需求说明:狗具有特有的接飞盘方法,企鹅具有特有的南极游泳方法。编写测试类分别调用各种具体宠物的特有方法,要求使用向下转型和instanceof判断宠物类型。
七、多态的应用
-
使用父类作为方法的形参,是Java中实现和使用多态的主要方式,如主人类中的cure方法:
public void cure(Pet pet) {
if (pet.getHealth() < 50)
pet.toHospital();
} -
使用父类作为方法的返回值,也是Java中实现和使用多态的主要方式。
练习:打印商品价格
需求说明:自定义类和方法,使用父类作为返回值实现打印不同类型商品价格功能。父类为Goods(商品类),子类为TVs(电视类)、Foods(食品类)。
八、总结要点
-
方法重写的规则:方法名、参数列表相同,返回值类型相同或是其子类,访问权限不能严于父类等。
-
instanceof的作用:判断一个引用类型所引用的对象是否是一个类的实例。
-
多态的作用:提高代码的可扩展性和可维护性,减少代码修改量。
-
多态的实现:基于方法重写,通过父类引用指向子类对象实现。
评论前必须登录!
注册