Flutter实体转模型问题:PurchaseOrderModel中Vendor类型适配方案咨询
Flutter实体转模型:子类属性类型与父类不兼容的解决方案
在开发Flutter应用时,实体类PurchaseOrder的vendor属性类型为Partner,但继承它的PurchaseOrderModel希望vendor是PartnerModel类型(PartnerModel是Partner的子类),直接继承会因类型不匹配报错。以下是几种实用的解决方案:
1. 用泛型让父类支持子类类型
改造PurchaseOrder为泛型类,允许指定关联的Partner子类类型,这样PurchaseOrderModel可以灵活指定自己需要的类型:
// 改造PurchaseOrder为泛型类 class PurchaseOrder<T extends Partner> { final DateTime? dateOrder; final DateTime? createDate; final String? origin; final T? vendor; final User? assignedUser; // 保留原有的assignedUser属性 const PurchaseOrder({ required this.dateOrder, this.createDate, this.origin, required this.assignedUser, required this.vendor, }); } // PurchaseOrderModel继承时指定泛型参数为PartnerModel class PurchaseOrderModel extends PurchaseOrder<PartnerModel> { final List? linePurchaseOrder; const PurchaseOrderModel({ required super.dateOrder, required super.createDate, required super.origin, required super.vendor, // 此处vendor自动适配为PartnerModel类型 required super.assignedUser, this.linePurchaseOrder, }); }
这种方式既保留了继承带来的代码复用,又解决了类型不兼容的问题,是最推荐的方案。
2. 采用组合代替继承
如果泛型不符合你的架构设计,可以用组合方式,让PurchaseOrderModel持有PurchaseOrder实例,同时扩展自己的属性:
class PurchaseOrderModel { final PurchaseOrder baseOrder; final PartnerModel? vendor; final List? linePurchaseOrder; PurchaseOrderModel({ required PurchaseOrder baseOrder, required this.vendor, this.linePurchaseOrder, }) : baseOrder = PurchaseOrder( dateOrder: baseOrder.dateOrder, createDate: baseOrder.createDate, origin: baseOrder.origin, assignedUser: baseOrder.assignedUser, vendor: vendor, // 将PartnerModel向上转型为父类Partner ); // 快捷访问baseOrder的属性,避免重复定义 DateTime? get dateOrder => baseOrder.dateOrder; }
这种方式摆脱了继承的类型限制,适合需要完全独立扩展模型属性的场景,但需要手动处理属性传递。
3. 添加模型转换方法
保持实体和模型的继承关系不变,通过扩展方法实现实体到模型的类型转换:
// 给Partner添加转Model的扩展方法 extension PartnerExtension on Partner { PartnerModel toModel() { return PartnerModel( id: id, displayName: displayName, ); } } // 给PurchaseOrder添加转Model的扩展方法 extension PurchaseOrderExtension on PurchaseOrder { PurchaseOrderModel toModel({List? linePurchaseOrder}) { return PurchaseOrderModel( dateOrder: dateOrder, createDate: createDate, origin: origin, assignedUser: assignedUser, vendor: vendor?.toModel(), // 将Partner转为PartnerModel linePurchaseOrder: linePurchaseOrder, ); } }
这种方式适合实体和模型职责划分清晰的场景(比如实体用于数据持久化,模型用于UI展示),通过转换方法实现类型适配。
内容的提问来源于stack exchange,提问作者Muhammad Usman
相关产品推荐
相关产品推荐

