为什么抽象类实例化不是dart中的运行时错误?

时间:2014-11-20 22:54:16

标签: dart abstract-class abstract

在许多语言中,如果您尝试实例化抽象类,则会出现编译时错误。 但是,在Dart中,编译时会收到警告并发出运行时异常AbstractClassInstantiationError

为什么?有人可以提供一个例子,编译这样的代码是合理的吗?

3 个答案:

答案 0 :(得分:5)

Dart尝试允许您在开发程序时运行程序。 这就是为什么许多其他语言中的编译时错误都是Dart中的编译时警告和运行时错误的原因。这包括" x是Foo"在Foo不存在的地方,使用不存在的类型进行类型注释,并调用部分(抽象)类的构造函数。

简而言之:因为它不是一个阻止程序编译的问题(不像语法错误可能意味着文件的其余部分被错误地解释),所以没有理由阻止你运行代码。只有当你点击实际取决于问题的分支时才会停止你的程序。

答案 1 :(得分:2)

抽象类中的答案似乎是factory constructor

abstract class Foo {
  factory Foo() { // make Foo appear to be instantiable
    return new Bar();
  }
  some(); // some abstract method
  Foo.name() {} just a named constructor
}

class Bar extends Foo {
  Bar():super.name(); // call named super constructor
  some() {} // implement abstract method
}

main() {
  print(new Foo()); // "instantiate" abstract Foo
}

输出:

Instance of 'Bar'

答案 2 :(得分:1)

问“编译这样的代码是合理的吗?”在Dart中并不是很有意义,因为Dart是一种解释语言 - 没有编译阶段。 Dart编辑如果认为您在运行中分析代码时出现类型错误,则会发出警告。

工厂构造函数可用于提供抽象类的“默认”具体实现,就像您在示例中所做的那样。这在Dart中使用得相当广泛。例如,如果您创建新的Map对象,实际上会获得LinkedHashMap个对象 - 请参阅this question and answer

在您的示例中,您没有实例化Foo的实例('new Foo'不会出现在任何地方),您正在实例化一个“Bar”。这是因为当调用工厂构造函数时,它的类的新实例不会自动实例化。