Dart中字段赋值未按预期生效的原因及解决方法
问题分析与解决
代码示例
class FooBase { String? name; FooBase({required this.name}); } class Foo extends FooBase{ final String name; Foo({required this.name}) : super(name: name); } void main() { final foo = Foo(name: 'foo'); final fooForm = foo; fooForm.name = 'bar'; print(fooForm.name); }
为什么实际打印"foo"?
因为Foo类中定义了final类型的同名成员变量name,它会隐藏父类FooBase的name属性:
- 执行
fooForm.name = 'bar'时,由于子类Foo的name是final不可赋值,Dart会隐式给父类FooBase的name赋值为'bar'; - 但打印
fooForm.name时,读取的是子类Foo中final的name(值始终是初始化时的'foo'),父类的name被隐藏无法直接访问,所以最终输出'foo'。
如何修改使其打印"bar"?
最合理的方案是移除子类中重复定义的name,让子类直接继承使用父类的name属性,避免成员隐藏问题:
修改后的代码:
class FooBase { String? name; FooBase({required this.name}); } class Foo extends FooBase{ // 移除子类的name定义,通过super复用父类的构造参数 Foo({required super.name}); } void main() { final foo = Foo(name: 'foo'); final fooForm = foo; fooForm.name = 'bar'; print(fooForm.name); // 输出"bar" }
如果确实需要子类保留独立的name成员,也可以通过显式访问父类属性的方式修改(不推荐,易造成混淆):
void main() { final foo = Foo(name: 'foo'); final fooForm = foo; // 显式转换为父类类型后赋值 (fooForm as FooBase).name = 'bar'; // 打印父类的name属性 print((fooForm as FooBase).name); // 输出"bar" }
内容的提问来源于stack exchange,提问作者TSR
相关产品推荐
相关产品推荐

