在实际项目中运用多态的核心是“基于抽象编程,适配不同实现”,通过父类/接口定义统一规范,子类实现具体逻辑,让代码具备灵活性和扩展性。以下结合真实项目场景,说明多态的具体运用方式、核心场景及最佳实践:
当业务需要支持多种同类功能(如支付方式、消息渠道),且每种功能的实现逻辑不同时,用多态可让上层代码与具体实现解耦。
系统需支持微信、支付宝、银联支付,每种支付的接口调用、签名逻辑不同,但上层订单模块只需“发起支付”动作。
实现方式:
Payment,声明统一方法pay(double amount)(支付金额)和getPayType()(获取支付类型)。 WeChatPayment、AlipayPayment、UnionPayPayment,各自实现pay()方法(调用对应平台API)。 Payment类型参数,直接调用pay(),无需关心具体支付方式。 // 1. 抽象接口:定义支付规范
public interface Payment {
boolean pay(double amount); // 支付方法,返回是否成功
String getPayType(); // 获取支付类型
}
// 2. 具体实现:微信支付
public class WeChatPayment implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("调用微信支付API,扣款" + amount + "元");
return true; // 实际项目需根据API返回结果判断
}
@Override
public String getPayType() {
return "微信支付";
}
}
// 3. 具体实现:支付宝支付
public class AlipayPayment implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("调用支付宝支付API,扣款" + amount + "元");
return true;
}
@Override
public String getPayType() {
return "支付宝支付";
}
}
// 4. 上层业务:订单支付(依赖抽象,不依赖具体实现)
public class OrderService {
// 接收Payment接口,支持任何支付实现类
public void processPayment(Payment payment, double amount) {
System.out.println("订单开始支付,方式:" + payment.getPayType());
boolean success = payment.pay(amount);
if (success) {
System.out.println("支付成功!");
} else {
System.out.println("支付失败!");
}
}
}
// 调用示例
public class Test {
public static void main(String[] args) {
OrderService orderService = new OrderService();
// 微信支付
orderService.processPayment(new WeChatPayment(), 199.9);
// 支付宝支付(无需修改OrderService代码)
orderService.processPayment(new AlipayPayment(), 299.9);
}
}效果:
UnionPayPayment实现类,业务层代码无需修改,符合“开闭原则”。 MockPayment)模拟支付结果,无需调用真实API,降低测试成本。当业务流程固定(如“数据导出”需经历“查询数据→处理数据→导出文件”),但部分步骤的实现不同(如导出Excel/PDF),用多态+模板方法模式可复用流程骨架,灵活替换细节。
导出功能需统一执行“查询→处理→导出”流程,但Excel和PDF的导出逻辑不同。
实现方式:
DataExporter,封装固定流程(export()方法),将可变步骤(exportFile())设为抽象方法。 ExcelExporter、PdfExporter分别实现exportFile()方法(生成Excel/PDF文件)。 // 1. 抽象父类:定义导出流程模板
public abstract class DataExporter {
// 固定流程:模板方法(final防止子类修改流程)
public final void export(String dataId) {
// 步骤1:查询数据(固定逻辑)
String data = queryData(dataId);
// 步骤2:处理数据(固定逻辑)
String processedData = processData(data);
// 步骤3:导出文件(可变逻辑,由子类实现)
exportFile(processedData);
}
// 固定方法:查询数据
private String queryData(String dataId) {
System.out.println("查询ID为" + dataId + "的数据");
return "原始数据-" + dataId;
}
// 固定方法:处理数据
private String processData(String data) {
return data + "-处理后";
}
// 抽象方法:导出文件(子类实现)
protected abstract void exportFile(String data);
}
// 2. 子类:Excel导出
public class ExcelExporter extends DataExporter {
@Override
protected void exportFile(String data) {
System.out.println("将数据[" + data + "]导出为Excel文件");
}
}
// 3. 子类:PDF导出
public class PdfExporter extends DataExporter {
@Override
protected void exportFile(String data) {
System.out.println("将数据[" + data + "]导出为PDF文件");
}
}
// 调用示例
public class ExportService {
public static void main(String[] args) {
DataExporter excelExporter = new ExcelExporter();
excelExporter.export("001"); // 输出:查询数据→处理数据→导出Excel
DataExporter pdfExporter = new PdfExporter();
pdfExporter.export("002"); // 输出:查询数据→处理数据→导出PDF
}
}效果:
CsvExporter子类,无需修改流程逻辑。当需要批量操作一组同类对象(如“商品列表”包含图书、电器、服装),用多态可遍历父类引用,自动调用子类的实现方法。
购物车中有多种商品(图书、电器),每种商品的折扣规则不同,需批量计算总价。
实现方式:
Product,声明抽象方法getFinalPrice()(获取最终价格)。 Book(折扣8折)、Electronic(满1000减200)分别实现getFinalPrice()。 List<Product>存储商品,遍历调用getFinalPrice()计算总价。 // 1. 抽象父类:商品
public abstract class Product {
protected String name;
protected double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
// 抽象方法:获取最终价格(子类实现折扣)
public abstract double getFinalPrice();
public String getName() {
return name;
}
}
// 2. 子类:图书(8折)
public class Book extends Product {
public Book(String name, double price) {
super(name, price);
}
@Override
public double getFinalPrice() {
return price * 0.8;
}
}
// 3. 子类:电器(满1000减200)
public class Electronic extends Product {
public Electronic(String name, double price) {
super(name, price);
}
@Override
public double getFinalPrice() {
return price >= 1000 ? price - 200 : price;
}
}
// 4. 购物车结算
public class CartService {
public static void main(String[] args) {
List<Product> cart = new ArrayList<>();
cart.add(new Book("Java编程思想", 108));
cart.add(new Electronic("小米手机", 2999));
double total = 0;
for (Product product : cart) {
double finalPrice = product.getFinalPrice();
System.out.println(product.getName() + "最终价格:" + finalPrice);
total += finalPrice;
}
System.out.println("购物车总价:" + total); // 输出:86.4 + 2799 = 2885.4
}
}效果:
Payment pay = new WeChatPayment())。OrderService)应依赖接口(Payment)或抽象类,而非具体实现类(WeChatPayment),降低耦合。 PaymentFactory根据类型创建不同Payment实现类。 (WeChatPayment)pay这类强转,否则违背多态设计初衷。多态让代码从“关注具体实现”转向“关注抽象行为”,大幅提升扩展性(新增实现无需修改上层代码)和可读性(统一接口语义清晰)。在实际项目中,凡是需要“同一行为多种实现”的场景(如支付、导出、消息通知),都是多态的典型应用场景。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。