给定一个abstract class
“Foo”,它有一个“值”的getter和setter
abstract class Foo<T> {
T get value;
set value(T newValue);
}
字符串
我试图覆盖getter和setter来使值成为final;
通过下面的实现
class Bar implements Foo<String> {
@override
final String value;
const Bar(this.value);
}
型
短绒器抱怨Missing concrete implementation of 'setter Foo.value'.
,
但如果我们加上
class Bar implements Foo<String> {
@override
final String value;
const Bar(this.value);
@override
set value(String newValue) => value = newValue;
}
型
当我们使用setter时
void main() {
const bar = Bar('hello');
bar.value = 'world';
print(bar.value);
}
型
我们没有收到关于使用setter作为最终值的ant警告,但在运行时我们会引发此错误
Uncaught RangeError: Maximum call stack size exceededError: RangeError: Maximum call stack size exceeded
型
这个问题似乎只针对二传手,因此,
1条答案
按热度按时间h5qlskok1#
没有正确的方法来禁用基类中的setter,因为这样做根本上是不正确的。派生类必须可以替换基类。如果派生类没有提供setter,那么它将不再提供基类的接口,并且将违反the substitution principle。考虑:
字符串
不可能发出任何编译时警告或错误;从静态分析来看,
updateFoo
的实现和调用都是法律的。相反,请考虑:
UnmodifiableListView
这样做的事情)的setter。此外,由于实现中的另一个错误,会发生特定的异常。当您这样做时:
型
那么
value = newValue;
语句将再次触发value
setter *,导致无限递归,正如错误消息所暗示的那样。如果你尝试这样做:型
那么你的
Bar
实现会因为试图重新分配_value
而产生一个编译时错误,也就是final
。如果你让_value
成为非final
,那么编译器会产生一个编译时错误,告诉你Bar
不能有const
构造函数。