首页 > 解决方案 > Dart:实例变量覆盖

问题描述

我对类实例变量覆盖的规则感到困惑

class S0 {
  num a;

  S0(this.a) {
    print("in S0 :$a");
  }
}

class S1 extends S0 {
  num a;

  S1(this.a) : super(a + 1) {
    print("in S1 :$a");
  }
}

main() {
  var b = S1(123);
  print(b.a);
}

以上是我的代码。我希望它打印:

在 S0 :124

在 S1 中:123

123

但结果是:

在 S0 :123

在 S1 中:123

123

为什么?谢谢!

标签: dart

解决方案


在 Dart 中,实例变量隐式地创建 getter 和(对于非final成员)setter 函数。也就是说,S0的接口是隐式的:

class S0 {
  num get a;
  set a(num value);

  S0(num a);
}

从这个角度来看,应该更清楚的是,当S0尝试访问时a,它使用它的 getter 方法,在这种情况下,它被覆盖S1,因此总是返回S1' 值。

施工顺序也很重要。构造派生类的实例S1将执行:

  1. 派生类的初始化列表 ( S1)。
  2. 来自基类 ( S0) 的初始化列表。
  3. 来自基类 ( S0) 的构造函数主体。
  4. 派生类 ( S1) 中的构造函数主体。

在第 2 步之后,该对象被认为构造得足够好,以便虚拟分派可以工作(即,可以调用派生类中的覆盖)。(这与诸如 C++ 之类的语言不同,其中对象纯粹从基类构造到派生类,并且不允许在构造函数中进行虚拟分派以防止在未构造的对象上调用方法。)


推荐阅读