Dart 抽象和多态性难题

Dart Abstraction & Polymorphism conundrum

请找到下面的飞镖片段

class A {
  String m1_a() {
    return "A -> m1_a()";
  }
}

abstract class B extends A {
  @override
  String m1_a();
}

class C extends B {}

void main() {
  B c_b = C();

  print(c_b.m1_a()); //"A -> m1_a()"
}

问。为什么 C 不强制覆盖由 class B 定义的抽象方法 m1_a() ?

B is declared as Abstract class so ideally m1_a() is also abstract method for child C !

Dart class 声明引入了 class(可以扩展和实例化)和 接口(可以实现)。 与其他类似语言不同,Dart 没有单独的 interface 声明,您可以从任何 class 中提取接口。 非抽象 class 必须始终具有其自身接口的实现。

class 声明中的具体方法,如 int foo() => 42;,将方法签名引入声明的接口和声明的 class 的实现,并且由于它们匹配, class 确实实现了接口。

一个抽象方法,和int foo();一样,只是在接口上增加了一个方法,不影响class。如果 class 是抽象的,并且没有 foo 的实现,那完全没问题。

在此示例中,B class 声明声明了 String m1_a();,它为 B 的接口添加了接口签名。这绝对没有影响,因为它也从 A 的接口继承了相同的签名。 此外,B class 继承了 class Am1_a 实现,因此它成功实现了它的接口,一切正常。

TL;DR: 抽象方法没有实现,对实现没有影响,只对接口有影响,所以它不会影响从 A.

继承的具体方法实现

抽象方法不影响继承的实现这一事实可用于更新子class 中的文档而不影响实现。示例:

class A {
  /// Does something using A.
  int foo() => something + _private();

  int _private() => _somethingSpecial();
}
class B {
  /// Does something using B.
  int foo();

  int _private() => _somethingSpecialForB();
}

这里你在B中改变了foo的行为,因为你改变了它依赖的私有函数的工作方式,但你没有改变A.foo中的共享代码。您仍然可以更新 B.foo 的文档以说明它有何不同。