La asignación de campo no funciona según lo previsto en 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);
}
Esperaría que este código imprimiera "bar" pero imprime "foo". ¿Porque?
¿Cómo hacer que imprima "barra"?
Tiene dos name
campos: uno FooBase
que proporciona implícitamente un captador y un definidor y final
otro en la Foo
clase derivada que proporciona solo un captador implícito.
Por lo tanto, cuando lo hace, fooForm.name = 'bar';
invoca al FooBase.name
definidor, ya que la clase derivada noFoo
lo anula . Cuando leas más tarde fooForm.name
, invocas el name
captador, que es anulado por la Foo
clase derivada para devolver la 'foo'
cadena original.
La moraleja es:
Anular campos suele ser una mala idea . (Hay una pelusa para advertir sobre esto ). En su lugar, anule los captadores y definidores.
De todos modos, intentar hacer que un campo no se pueda escribir en una clase derivada es una mala idea. Al hacerlo, se rompe la interfaz y se rompe el principio de sustituibilidad de Liskov .