Dart如何覆写父类toMap方法 转型父类后调用对应实现
问题本质
这是Dart面向对象体系下动态分派的正常表现:实例方法的调用优先级匹配对象运行时的实际类型,和变量的声明类型无关,属于多态特性的默认实现逻辑。你覆写了父类的toMap方法后,只要实际运行的是B类实例,不管上层用什么父类型承接,默认都会调用子类的覆写实现。
解决方案
以下是不同场景下的可行处理方式:
方案1:抽离父类逻辑为独立静态方法(最稳定,推荐)
把A类中原本toMap的逻辑抽成不会被子类覆写的静态方法,需要调用父类逻辑时直接调用该静态方法即可,完全不受多态调度影响:
class A { String str1; A(this.str1); Map<String, dynamic> toMap() => aToMap(this); // 抽离A的toMap独立逻辑,不会被子类覆写 static Map<String, dynamic> aToMap(A instance) => { 'str1': instance.str1, }; } class B extends A { String str2; B(this.str2, String str1) : super(str1); Map<String, dynamic> toMap() => { 'str2': str2, 'str1': str1, }; } void test(A a) { // 直接调用A的静态方法,强制走A的实现逻辑 print(A.aToMap(a)); }
方案2:用扩展方法实现静态调度
扩展方法是根据变量的声明类型做静态调度的,不会走实例方法的动态分派逻辑,适合不想修改原有类结构的场景:
// 给A类写扩展方法,所有声明为A类型的变量调用该方法都会走A的逻辑 extension AExt on A { Map<String, dynamic> toMapAsA() => { 'str1': str1, }; } void test(A a) { print(a.toMapAsA()); }
方案3:显式类型分支判断(仅适合子类数量少的临时场景)
如果不想修改原有类的结构,也可以在调用侧做类型判断,手动构造符合要求的返回值:
void test(A a) { if(a is B) { print({'str1': a.str1}); return; } print(a.toMap()); }
内容的提问来源于stack exchange,提问作者ccd
相关产品推荐
相关产品推荐

