在许多语言中,如果您尝试实例化抽象类,则会出现编译时错误。
但是,在Dart中,编译时会收到警告并发出运行时异常AbstractClassInstantiationError
。
为什么?有人可以提供一个例子,编译这样的代码是合理的吗?
答案 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”。这是因为当调用工厂构造函数时,它的类的新实例不会自动实例化。