第一部分:多态基础概念
多态是面向对象的核心特性,允许同一接口表现出不同实现
学习目标
理解多态的三种实现方式:方法重载、方法重写、对象多态
1
什么是多态
多态字面意思是"多种形态",在Java中表现为:
- 编译时多态:方法重载
- 运行时多态:方法重写 + 向上转型
// 运行时多态示例:同一接口,不同实现
Animal myAnimal;
myAnimal = new Dog();
myAnimal.makeSound(); // 输出:汪汪汪
myAnimal = new Cat();
myAnimal.makeSound(); // 输出:喵喵喵
2
多态的必要条件
1. 继承关系
存在父类与子类的继承关系
2. 方法重写
子类重写父类的方法
3. 向上转型
父类引用指向子类对象
第二部分:向上转型详解
向上转型是Java实现多态的核心机制,自动完成类型转换
学习目标
掌握向上转型的语法、特点及内存模型
1
基本语法
// 父类引用指向子类对象(自动类型转换)
Parent p = new Child();
// 实际开发中的常见场景
List list = new ArrayList();
Map map = new HashMap();
2
内存模型分析
栈内存
animalRef → [堆地址0x2000]
堆内存 - Dog对象
Animal部分:name, age
Dog特有:breed, tailWagging
方法表:Dog.makeSound()
向上转型后,通过父类引用只能访问父类定义的属性和方法
3
向上转型的特点
- 自动完成:无需强制类型转换
- 安全:不会引发ClassCastException
- 限制:丢失子类特有方法
- 多态:运行时调用实际对象的方法
第三部分:instanceof运算符
instanceof用于判断对象的真实类型,避免类型转换异常
学习目标
掌握instanceof语法、使用场景及最佳实践
1
基本语法
Object obj = new String("Hello");
// 判断对象是否为特定类型
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str.length());
}
2
完整示例
public class AnimalHospital {
public void treatAnimal(Animal animal) {
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.wagTail();
}
else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.purr();
}
else {
System.out.println("通用治疗");
}
}
}
3
Java 14+ 模式匹配
// Java 14+ 支持的模式匹配语法
public void processAnimal(Animal animal) {
if (animal instanceof Dog dog) {
// 直接定义变量dog,无需强制转换
dog.bark();
}
}
第四部分:图形绘制系统实战
通过完整的图形绘制案例,综合运用多态、向上转型和instanceof
1
创建图形基类
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public abstract double getArea();
public abstract void draw();
}
2
创建具体图形类
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("绘制一个" + color + "的圆,半径:" + radius);
}
}
public class Rectangle extends Shape {
private double width, height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
@Override
public void draw() {
System.out.println("绘制一个" + color + "的矩形,面积:" + getArea());
}
}
3
多态应用 - 图形管理器
import java.util.*;
public class ShapeManager {
private List<Shape> shapes = new ArrayList<>();
public void addShape(Shape shape) {
shapes.add(shape);
}
public void drawAllShapes() {
for (Shape shape : shapes) {
shape.draw(); // 多态调用
}
}
public double getTotalArea() {
double total = 0;
for (Shape shape : shapes) {
total += shape.getArea(); // 多态计算
}
return total;
}
public void printCircleAreas() {
for (Shape shape : shapes) {
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
System.out.println("圆形面积:" + circle.getArea());
}
}
}
}
4
测试多态功能
public class ShapeTest {
public static void main(String[] args) {
ShapeManager manager = new ShapeManager();
// 向上转型:子类对象赋给父类引用
Shape circle = new Circle("红色", 5.0);
Shape rectangle = new Rectangle("蓝色", 4.0, 6.0);
manager.addShape(circle);
manager.addShape(rectangle);
// 多态调用
manager.drawAllShapes();
System.out.println("总面积:" + manager.getTotalArea());
}
}
第五部分:常见错误与最佳实践
总结多态使用中的常见错误及最佳实践建议
常见错误1:类型转换异常
错误代码:
Animal animal = new Dog();
Cat cat = (Cat) animal; // 运行时异常:ClassCastException
正确做法:
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
}
常见错误2:访问子类特有方法
错误代码:
Animal animal = new Dog();
animal.wagTail(); // 编译错误:找不到方法
解决方案:
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.wagTail();
}
最佳实践
- 优先使用接口或抽象类作为参数类型
- 减少instanceof的使用,考虑多态设计
- 使用泛型避免类型转换
- 遵循里氏替换原则
- 使用工厂模式创建多态对象
知识总结
多态核心要点
- 同一行为,不同表现
- 运行时动态绑定
- 基于继承和方法重写
- 提高代码可扩展性
向上转型特点
- 自动类型转换
- 安全无异常
- 丢失子类特性
- 保持方法多态性
instanceof用法
- 类型安全检查
- 避免转换异常
- 结合强制类型转换
- Java 14+支持模式匹配
动手练习
- 创建Vehicle基类(brand, speed属性)
- 创建Car、Bike子类,重写run方法
- 使用多态创建Vehicle数组存储不同车辆
- 遍历数组调用run方法观察多态效果
- 使用instanceof统计Car和Bike的数量
- 实现VehicleFactory工厂类创建对象