1、多态(Polymorphism) 的定义
- 一个 引用类型的变量 可以指向 多种实际对象,这一点称为多态(polymorphism)。
- 引用类型的变量 在运行时能够自动地选择适当的方法,称为 动态绑定(dynamic binding)。
- 这种多态也叫做:运行时多态。
- 多态 是一项让程序员“将 改变的事物 与 未变的事物 分离 开来”的重要技术。
- 可以 消除 类型 之间的 耦合关系。提高代码的可扩展性和复用性。
- 运行时多态 的 实现:通过方法的重写来实现的。
- 父类引用可以指向子类对象,通过方法重写,根据子类不同,完成的功能也不同。
- 核心机制 / 实现条件:
- 1、向上转型(Upcasting)。
- 2、动态绑定(Dynamic Binding)
- 3、方法重写(Override)
class Animal {
void sound() {
System.out.println("动物叫声");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("汪汪汪");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound();
}
}
2、向上转型
- 向上转型(Upcasting) 是指将 子类对象 赋值给 父类引用 的过程。
- 这是 面向对象编程 中 多态性 的核心体现。
- 转型过程是 安全的 且由 编译器 自动完成(无需强制转换 )。
- 局部变量 赋值中的 子类对象 赋值给 父类引用 。
class Cat extends Animal {
int age;
public Cat(int age) {
this.age = age;
}
@Override
public void eat() {
System.out.println("Cat is eating fish");
}
public static void main(String[] args) {
Animal animal = new Cat(3);
System.out.println(animal.age);
animal.eat();
Cat cat = new Cat(3);
System.out.println(cat.age);
cat.eat();
}
}
public class Animal {
int age;
public void eat() {
System.out.println("Animal is eating");
}
}
interface PromotionStrategy {
double applyPromotion(double price);
}
class FullReductionStrategy implements PromotionStrategy {
@Override
public double applyPromotion(double price) {
if (price >= 200) return price - 50;
return price;
}
}
class DiscountStrategy implements PromotionStrategy {
@Override
public double applyPromotion(double price) {
return price * 0.8;
}
}
class NoPromotionStrategy implements PromotionStrategy {
@Override
public double applyPromotion(double price) {
return price;
}
}
class OrderContext {
private PromotionStrategy strategy;
public OrderContext(PromotionStrategy strategy) {
this.strategy = strategy;
}
public double calculateFinalPrice(double originalPrice) {
return strategy.applyPromotion(originalPrice);
}
}
public class StrategyDemo {
public static void main(String[] args) {
OrderContext order = new OrderContext(new NoPromotionStrategy());
System.out.println("原价100,无优惠: " + order.calculateFinalPrice(100));
order = new OrderContext(new FullReductionStrategy());
System.out.println("原价250,满减后: " + order.calculateFinalPrice(250));
order = new OrderContext(new DiscountStrategy());
System.out.println("原价100,8折后: " + order.calculateFinalPrice(100));
}
}
特性 | 向上转型 | 向下转型 |
---|
转型方向 | 子类 → 父类 | 父类 → 子类 |
安全性 | 自动安全(编译器支持) | 需显式转换且可能抛出异常 |
典型用途 | 实现多态、统一接口处理 | 恢复子类特有功能 |
3、多态所需的支持
- 多态这种特性也需要编程语言提供特殊的语法机制来实现。
- 1、编程语言要支持继承 。
- 2、编程语言要支持方法重写 。
- 3、编程语言要支持父类引用可以指向子类对象。
4、多态的应用场景
- 多态也是很多设计模式、设计原则、编程技巧 的代码实现基础。
- 策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、
- 利用多态去掉冗长的 if-else 语句等等。
- 使用父类做方法的形参,实参可以是该父类的任意子类类型
- 使用父类做方法的返回值类型,返回值可以改父类的任意子类对象。
5、广义上的 其它类型的多态
1、编译时多态(静态多态)-- 通过方法的重载来实现的。
- 在程序执行前,该方法就能够确定所在的类,此时由编译器或其它链接程序实现。
- static 修饰的方法
- final 修饰的方法
- private 修饰的方法
- 方法重载:
- 在同一个类中,允许多个方法使用同一个名字,但是方法的参数不同,完成的功能也不同。
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3));
System.out.println(calc.add(2.5, 3.5));
}
}
2、参数多态 / 泛型多态
- 定义:
- 用泛型 (Generics) 实现代码对多种数据类型的通用操作,类型参数在编译时或运行时确定
- 实现方式:
class Box<T> {
private T content;
void setContent(T content) {
this.content = content;
}
T getContent() {
return content;
}
}
public class Main {
public static void main(String[] args) {
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
Box<Integer> intBox = new Box<>();
intBox.setContent(123);
}
}