注意:这个问题已经过时了;已从Dart中删除
interface
声明语法:
Proposal to eliminate interface declarations from Dart
“在Dart中,每个类都会产生一个隐式接口。现在已经实现了这个特性,实际上可以从语言中消除接口声明。接口声明被纯粹的抽象类所取代。”
据我所知,在Dart中实例化接口是不可能的。如果我只是尝试构造new MyInterface()
,无论是否定义了构造函数,我都会遇到运行时错误(try it):
NoSuchMethodException - receiver: '' function name: 'MyInterface$$Factory' arguments: []]
interface MyInterface {}
interface MyInterface {
MyInterface();
}
如果我尝试使用工厂构造函数,返回实现的实例,则会出现编译时错误(try it):
SyntaxError: factory members are not allowed in interfaces
class MyImplementation implements MyInterface {
MyImplementation();
}
interface MyInterface {
factory MyInterface() { return new MyImplementation(); }
}
然而,这似乎与Dart的核心库中的List<E>
1 是接口 2 的现实相矛盾,但它有几个构造函数并且可以被实例化。例如,这工作正常(try it):
main() {
var list = new List();
list.add(5);
print(list.last());
}
为什么List
和许多其他内置接口可以实例化?是否有一些方法我错过了或者他们只是作为内置类型接受特殊处理?
1 Dart: Libraries: corelib: interface List<E>
2 “很多Dart核心库都是根据接口定义的。” 3
3 Dart: Tutorial: Interfaces
答案 0 :(得分:9)
定义接口的语法是:
interfaceDefinition:
interface identifier typeParameters? superinterfaces? factorySpecification? `{' (interfaceMemberDefinition)* `}'
请注意,factorySpecification
必须位于界面正文之前,而不是位于界面之内。
这就是你写它的方式:
interface MyInterface default MyImplementation {
}
class MyImplementation implements MyInterface {
MyImplementation();
}
或者,如果您想要完整的通用定义:
interface MyInterface<E> default MyImplementation<E> {
MyInterface(x);
}
class MyImplementation<E> implements MyInterface<E> {
MyImplementation(this.x);
E x;
}
修改:有关更完整的示例,您可以在https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/corelib/src/list.dart阅读interface List<E>
的源代码,相关的class ListFactory<T>
来源位于{{ 3}}
答案 1 :(得分:2)
Dart将factory
用于两个不同的事情:factory classes 和factory 构造函数。工厂类看起来像这样:
interface List default ConcreteList {
List();
...
}
class ConcreteList implements List {
ConcreteList() {}
}
这样做可以让您在界面中定义构造函数。通过执行new List()
(或任何接口)调用它们时,它知道实际实例化ConcreteList
,因为这是您为该接口指定的工厂类。
这为您提供了一种在接口后面完全封装具体类型的方法,甚至包括构造点。
工厂构造函数如下所示:
class Point {
static _zero;
int x, y;
Point(this.x, this.y) {}
factory Point.zero() {
if (_zero == null) _zero = new Point(0, 0);
return _zero;
}
}
这里,Point.zero
是(命名的)工厂构造函数。工厂构造函数允许您抽象实例化。您像常规构造函数一样调用它们,但它们不会自动生成对象的新实例。相反,你可以自由地在构造函数的主体中做任何你想做的事情。在这里,每次你这样做:
new Point.zero();
您将获得相同的缓存_zero
对象,即使您每次都使用new
,因为它们的工厂构造函数始终返回相同的对象。它们有几个用途:
new
的类,但在某些情况下,您可能实际上想要返回它的子类以便专门化它的行为。工厂构造函数允许您在不必更改调用站点的情况下执行此操作。