一、学习目标
- 理解面向对象三大特性:多态的概念与价值
- 掌握多态的实现条件
- 学会向上转型、向下转型语法与场景
- 分清成员变量、成员方法在多态下的访问规则
- 理解动态绑定机制
- 掌握转型异常判断
instanceof
二、什么是多态
多态:同一个行为,不同对象执行有不同表现形态。 举例: 父类 Animal 有 eat () 方法,Dog、Cat 子类重写 eat (); 同样调用 eat (),狗是啃骨头,猫是吃鱼,这就是多态。
多态核心好处:程序扩展性强,新增子类不用修改原有业务代码。
三、多态实现的四个必备条件(缺一不可)
- 存在继承 / 实现关系(extends /implements)
- 子类重写父类方法
- 父类引用指向子类对象(向上转型)
- 调用重写的方法
基础代码演示
java运行
// 父类
abstract class Animal {
public abstract void eat();
}
// 子类狗
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗啃骨头");
}
}
// 子类猫
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Test {
public static void main(String[] args) {
// 父类引用指向子类对象:向上转型,多态写法
Animal a1 = new Dog();
Animal a2 = new Cat();
// 同一个eat方法,不同对象不同实现(多态体现)
a1.eat();
a2.eat();
}
}
运行结果:
plaintext
狗啃骨头
猫吃鱼
四、向上转型(自动转换)
语法
java
运行
父类类型 引用变量 = new 子类对象();
- 自动转换,无需强转
- 访问权限限制:
- 只能调用父类中存在的方法 / 变量
- 子类独有的方法无法直接调用
示例缺陷
java运行
class Dog extends Animal{
@Override
public void eat(){}
// 子类独有方法
public void watchHome(){
System.out.println("看家");
}
}
public static void main(String[] args) {
Animal a = new Dog();
a.eat(); // 正常,父类有eat
// a.watchHome(); 编译报错,父类没有该方法
}
五、向下转型(强制转换)
需求:向上转型后,想调用子类独有方法,需要向下强制转回子类类型。
语法
java运行
子类类型 变量 = (子类类型)父类引用;
java运行
Animal a = new Dog();
Dog dog = (Dog) a;
dog.watchHome(); // 可以调用子类独有方法
转型风险:类型转换异常 ClassCastException
如果父类引用实际指向的是另一个子类,强转会报错
java运行
Animal a = new Cat();
Dog dog = (Dog) a; // 运行报错:Cat不能转Dog
六、instanceof 关键字(安全转型必备)
作用:判断引用变量实际对象是不是某个类 / 子类,返回布尔值 语法:
java运行
引用变量 instanceof 类名
标准安全转型写法:
java运行
Animal a = new Dog();
if(a instanceof Dog){
Dog dog = (Dog)a;
dog.watchHome();
}
if(a instanceof Cat){
Cat cat = (Cat)a;
}
七、多态访问规则(重点必背)
1. 成员方法:编译看左边,运行看右边(动态绑定)
- 编译阶段:检查父类是否有该方法,没有则报错
- 运行阶段:执行子类重写后的方法
2. 成员变量:编译看左边,运行看左边(静态绑定)
变量不存在重写,永远取引用类型(父类)的变量 完整对比案例:
java运行
class Father{
String name = "父类";
public void show(){
System.out.println("父类方法");
}
}
class Son extends Father{
String name = "子类";
@Override
public void show(){
System.out.println("子类方法");
}
}
public class Test{
public static void main(String[] args) {
Father f = new Son();
// 变量:看左边Father
System.out.println(f.name); // 输出:父类
// 方法:运行看右边Son
f.show(); // 输出:子类方法
}
}
八、多态经典应用:方法参数多态
定义统一方法接收父类类型,所有子类对象都能传入,扩展性极强
java运行
public class TestAnimal {
// 参数为父类,所有子类都可以传入
public static void feed(Animal a){
a.eat();
}
public static void main(String[] args) {
feed(new Dog());
feed(new Cat());
}
}
后续新增兔子 Rabbit 子类,不需要修改 feed 方法,直接传入即可,符合开闭原则。
九、向上 / 向下转型总结
表格
| 转型 | 语法 | 转换方式 | 特点 |
|---|---|---|---|
| 向上转型 | 父类 引用 = new 子类 () | 自动转换 | 只能访问父类方法,丢失子类独有功能 |
| 向下转型 | 子类 引用 = (子类) 父类引用 | 强制转换 | 可调用子类独有方法,有类型转换异常风险,需配合 instanceof |
十、常见易错点
- 多态父类引用无法直接调用子类独有方法,必须向下转型
- 向下转型不判断 instanceof,容易运行时报 ClassCastException
- 成员变量不存在重写,多态下永远取父类变量
- 静态方法不存在重写,多态调用静态方法只看左边引用类型
十一、课堂练习
- 抽象父类 Shape,抽象方法 getArea () 求面积
- 子类 Rect 矩形、Circle 圆形重写求面积
- 写静态方法 printArea (Shape s),传入任意图形输出面积(多态参数)
十二、课后作业
- 接口 USB,方法 work ();鼠标 Mouse、键盘 Keyboard 实现 USB
- 多态写法:USB usb1 = new Mouse (); USB usb2 = new Keyboard ();
- 使用 instanceof 判断类型,向下转型调用子类独有方法
本课小结
- 多态三要素:继承 / 实现、方法重写、父类引用指向子类对象;
- 方法动态绑定:编译看父类,运行执行子类重写方法;
- 向上转型自动转换,向下强制转型,配合 instanceof 避免异常;
- 多态最大优势:统一参数,拓展性强。

788

被折叠的 条评论
为什么被折叠?



