多态
多态是面向对象编程的核心特性之一。
多态概念
什么是多态
多态指同一操作作用于不同对象,产生不同的执行结果。
Java
// 同样的方法,不同的表现
Animal animal;
animal = new Dog();
animal.speak(); // 输出:汪汪汪
animal = new Cat();
animal.speak(); // 输出:喵喵喵
多态的三个条件
- 继承关系存在
- 子类重写父类方法
- 父类引用指向子类对象
Java
// 条件1:继承
public class Animal {
public void speak() {
System.out.println("动物叫");
}
}
public class Dog extends Animal {
// 条件2:重写方法
@Override
public void speak() {
System.out.println("汪汪汪");
}
}
// 条件3:父类引用指向子类对象
Animal animal = new Dog(); // 多态
animal.speak(); // 输出:汪汪汪(调用子类方法)
多态实现
父类引用指向子类对象
Java
// 多态形式:父类类型 引用 = new 子类类型();
Animal a1 = new Dog();
Animal a2 = new Cat();
Animal a3 = new Bird();
// 编译时看父类,运行时看子类
a1.speak(); // 汪汪汪(Dog的方法)
a2.speak(); // 喵喵喵(Cat的方法)
a3.speak(); // 叽叽喳喳(Bird的方法)
多态示例
Java
public class Shape {
public void draw() {
System.out.println("画图形");
}
}
public class Circle extends Shape {
@Override
public void draw() {
System.out.println("画圆形");
}
}
public class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("画矩形");
}
}
// 使用多态
Shape shape = new Circle();
shape.draw(); // 画圆形
shape = new Rectangle();
shape.draw(); // 画矩形
多态优势
统一调用方式
Java
// 不使用多态:分别处理每种类型
Dog dog = new Dog();
dog.speak();
Cat cat = new Cat();
cat.speak();
// 使用多态:统一处理
Animal[] animals = {new Dog(), new Cat(), new Bird()};
for (Animal a : animals) {
a.speak(); // 统一调用,各自表现不同
}
扩展性强
Java
// 添加新子类,不影响现有代码
public class Fish extends Animal {
@Override
public void speak() {
System.out.println("鱼摆尾");
}
}
// 原有代码无需修改,直接使用
Animal animal = new Fish();
animal.speak(); // 鱼摆尾
方法参数多态
Java
public void feed(Animal animal) {
animal.eat(); // 可接收任何Animal子类
}
// 调用
feed(new Dog());
feed(new Cat());
feed(new Bird());
类型转换
向上转型(自动)
子类对象赋给父类引用,自动转换。
Java
// 向上转型:子类 → 父类(自动)
Animal animal = new Dog(); // 自动向上转型
// 向上转型后只能调用父类方法
animal.speak(); // 正确(父类有此方法)
// animal.bark(); // 错误(父类没有此方法)
向下转型(手动)
父类引用转回子类类型,需要强制转换。
Java
Animal animal = new Dog();
// 向下转型:父类 → 子类(强制)
Dog dog = (Dog) animal;
dog.bark(); // 可以调用子类特有方法
// 错误转换:类型不匹配
Animal animal = new Cat();
Dog dog = (Dog) animal; // 运行时错误:ClassCastException
instanceof类型检查
向下转型前应检查类型,避免异常。
Java
Animal animal = new Dog();
// 类型检查
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // 安全转换
}
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
多态中的方法调用
编译时与运行时
Java
Animal animal = new Dog();
// 编译时:检查Animal类是否有speak方法
// 运行时:执行Dog类的speak方法(动态绑定)
animal.speak(); // 编译看Animal,运行看Dog
成员变量不参与多态
Java
public class Animal {
String name = "动物";
}
public class Dog extends Animal {
String name = "狗"; // 属性不重写,是遮蔽
}
Animal animal = new Dog();
System.out.println(animal.name); // 输出:动物(父类属性)
// 属性看编译时类型,方法看运行时类型
成员变量不具有多态,编译时绑定。
接口实现多态
接口多态
Java
// 定义接口
public interface USB {
void work();
}
// 实现类
public class Mouse implements USB {
@Override
public void work() {
System.out.println("鼠标工作");
}
}
public class Keyboard implements USB {
@Override
public void work() {
System.out.println("键盘工作");
}
}
// 接口多态
USB usb = new Mouse();
usb.work(); // 鼠标工作
usb = new Keyboard();
usb.work(); // 键盘工作
接口参数多态
Java
public void useUSB(USB usb) {
usb.work(); // 可接收任何USB实现类
}
useUSB(new Mouse());
useUSB(new Keyboard());
多态应用场景
策略模式
Java
public interface PaymentStrategy {
void pay(double amount);
}
public class CreditCard implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("信用卡支付" + amount);
}
}
public class Alipay implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("支付宝支付" + amount);
}
}
// 使用
PaymentStrategy strategy = new CreditCard();
strategy.pay(100); // 信用卡支付
strategy = new Alipay();
strategy.pay(100); // 支付宝支付
工厂模式
Java
public Animal createAnimal(String type) {
if ("dog".equals(type)) {
return new Dog();
} else if ("cat".equals(type)) {
return new Cat();
}
return null;
}
Animal animal = createAnimal("dog");
animal.speak(); // 汪汪汪
要点总结
- 多态是同一方法在不同对象有不同表现
- 多态三条件:继承、重写、父类引用指向子类
- 编译看父类,运行看子类(动态绑定)
- 向上转型:子类→父类(自动)
- 向下转型:父类→子类(强制,需instanceof检查)
- instanceof检查对象是否是某类型
- 成员变量不具有多态(编译时绑定)
- 接口实现也可实现多态
- 多态优势:统一调用、扩展性强
- 多态应用:策略模式、工厂模式等
📝 发现内容有误?点击此处直接编辑