skip to Main Content
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);
}

I would expect this code to print "bar" but it prints "foo". Why so?

How to make it print "bar" ?

2

Answers


  1. You have two name fields: one in FooBase that implicitly provides a getter and a setter and a final one in the derived Foo class that provides only an implicit getter.

    Therefore when you do fooForm.name = 'bar'; it invokes the FooBase.name setter since that is not overridden by the derived Foo class. When you later read fooForm.name, you invoke the name getter, which is overridden by the derived Foo class to return the original 'foo' string.

    The morals are:

    Login or Signup to reply.
  2. when you access fooForm.name, it is referring to the name property in the Foo class rather than the name property in the FooBase class.
    To make it print "bar", you can remove the name property from the Foo class and directly use the name property from the FooBase class. Here’s the modified code:

    class FooBase {
      String? name;
    
      FooBase({required this.name});
    }
    
    class Foo extends FooBase {
      Foo({required String name}) : super(name: name);
    }
    
    void main() {
      final foo = Foo(name: 'foo');
      final fooForm = foo as FooBase;
      fooForm.name = 'bar';
      print(fooForm.name);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search