Dart中重写BaseFoo.commit方法时子类参数不合法问题
Dart 方法重写参数类型不匹配问题解决
你遇到的问题是:定义了抽象类BaseBar和BaseFoo,BaseFoo包含接收BaseBar类型参数的commit方法,继承BaseFoo后尝试将commit的参数改为BaseBar的子类Bar,但触发重写错误。
代码示例
abstract class BaseBar {} abstract class BaseFoo { void commit(BaseBar bar); } // 实现代码 class Bar extends BaseBar { final String id; Bar(this.id); } class Foo extends BaseFoo { @override void commit(Bar bar) {} }
错误信息(翻译后)
'Foo.commit' ('void Function(Bar)')不是对'BaseFoo.commit' ('void Function(BaseBar)')的有效重写。
问题原因
Dart的方法重写遵循里氏替换原则:子类必须能替代父类使用。父类BaseFoo的commit方法接受所有BaseBar类型的参数(包括BaseBar的任意子类),但子类Foo的commit只接受Bar类型,这意味着当用BaseFoo类型的变量调用commit时,传入其他BaseBar子类会导致子类方法无法处理,因此这种重写是不被允许的。
解决方案
方案1:使用泛型(推荐)
让BaseFoo通过泛型约束参数类型,子类可以指定具体的子类类型,既满足重写规则,又能精准限制参数:
abstract class BaseBar {} abstract class BaseFoo<T extends BaseBar> { void commit(T bar); } class Bar extends BaseBar { final String id; Bar(this.id); } class Foo extends BaseFoo<Bar> { @override void commit(Bar bar) { // 直接处理Bar类型参数 print(bar.id); } }
方案2:保留父类参数类型,内部做类型校验
如果不想使用泛型,可以在子类方法中保留BaseBar参数,通过类型检查确保传入的是Bar类型:
abstract class BaseBar {} abstract class BaseFoo { void commit(BaseBar bar); } class Bar extends BaseBar { final String id; Bar(this.id); } class Foo extends BaseFoo { @override void commit(BaseBar bar) { if (bar is! Bar) { throw ArgumentError('参数必须为Bar类型'); } // 类型转换后安全使用 final barInstance = bar as Bar; print(barInstance.id); } }
内容的提问来源于stack exchange,提问作者TSR
相关产品推荐
相关产品推荐

