为什么Dart内置的List接口可以被实例化?

发布于 2024-12-09 04:51:26 字数 2261 浏览 1 评论 0 原文

注意:这个问题已过时; interface 声明语法已从 Dart 中删除:


据我所知可以看出,在 Dart 中实例化接口是不可能的。如果我只是尝试构造一个 new MyInterface(),无论是否定义了构造函数,我都会收到运行时错误 (尝试一下):

NoSuchMethodException - receiver: '' function name: 'MyInterface$$Factory' arguments: []]
interface MyInterface {}      
interface MyInterface {
  MyInterface();
}

如果我尝试使用工厂构造函数,返回实现的实例,则会收到编译时错误 (尝试一下):

SyntaxError: factory members are not allowed in interfaces
class MyImplementation implements MyInterface {
  MyImplementation();
 }

interface MyInterface {
  factory MyInterface() { return new MyImplementation(); }
}

然而,这似乎与 List< 的现实相矛盾Dart 核心库中的;E>1 是一个接口2,但它有多个构造函数并且可以实例化。例如,这工作正常(尝试一下):

main() {
  var list = new List();
  list.add(5);
  print(list.last());
}

为什么可以List 和许多其他内置接口被实例化?我是否错过了某些方法,或者它们只是作为内置类型接受特殊处理?


1 Dart:库:corelib:接口列表
2 “Dart 核心库的大部分内容都是根据接口定义的。”3
3
Dart:教程:接口

Notice: This question is obsolete; the interface declaration syntax has been removed from Dart:


As far as I've been able to tell, it's impossible to instantiate an interface in Dart. If I simply try to construct a new MyInterface(), with or without a constructor defined, I get a run-time error (try it):

NoSuchMethodException - receiver: '' function name: 'MyInterface$Factory' arguments: []]
interface MyInterface {}      
interface MyInterface {
  MyInterface();
}

If I try to use a factory constructor instead, returning an instance of an implementation, I get a compile-time error (try it):

SyntaxError: factory members are not allowed in interfaces
class MyImplementation implements MyInterface {
  MyImplementation();
 }

interface MyInterface {
  factory MyInterface() { return new MyImplementation(); }
}

However, this seems at-odds with the reality that List<E>1 in Dart's core library is an interface2, yet it has several constructors and can be instantiated. For example, this works fine (try it):

main() {
  var list = new List();
  list.add(5);
  print(list.last());
}

Why can List and many other built-in interfaces be instantiated? Is there some method I missed or are they just receiving special treatment as built-in types?


1 Dart: Libraries: corelib: interface List<E>
2 "Much of the Dart Core Library is defined in terms of interfaces."3
3 Dart: Tutorial: Interfaces

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃→可爱长大的 2024-12-16 04:51:26

定义接口的语法是:

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;
}

编辑:要获得更完整的示例,你可以阅读接口List位于https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/corelib/src/list.dart 和关联的 class ListFactory< T> 源位于 https://code.google.com /p/dart/source/browse/branches/bleeding_edge/dart/runtime/lib/array.dart

The syntax for defining an interface is:

interfaceDefinition:
    interface identifier typeParameters? superinterfaces? factorySpecification? `{' (interfaceMemberDefinition)* `}'

Notice that the factorySpecification must come before the body of the interface rather than inside it.

So this is how you write it:

interface MyInterface default MyImplementation {

}

class MyImplementation implements MyInterface {
  MyImplementation();
}

Or if you want to go for the full generic definition:

interface MyInterface<E> default MyImplementation<E> {
    MyInterface(x);
}

class MyImplementation<E> implements MyInterface<E> {
  MyImplementation(this.x);
  E x;
}

Edit: For a more complete example, you can read the source code for the interface List<E> at https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/corelib/src/list.dart and the associated class ListFactory<T> source is at https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/runtime/lib/array.dart

柒七 2024-12-16 04:51:26

Dart 使用工厂来实现两种不同的目的:工厂类和工厂构造函数。工厂类如下所示:

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,因为它们工厂构造函数总是返回相同的值。它们有几个用途:

  1. 返回以前缓存的对象,就像我们在这里所做的那样。
  2. 返回一个子类。这有点像接口的工厂类。您可能有一个可以new的类,但在某些情况下您可能实际上希望返回它的子类以专门化其行为。工厂构造函数让您无需更改调用点即可做到这一点。

Dart uses factory for two different things: factory classes, and factory constructors. A factory class looks like this:

interface List default ConcreteList {
  List();
  ...
}

class ConcreteList implements List {
  ConcreteList() {}
}

What this does is it lets you define constructors in an interface. When you invoke them by doing new List() (or whatever your interface is), it knows to actually instantiate ConcreteList because that's the factory class you've specified for that interface.

This gives you a way to completely encapsulate a concrete type behind an interface, including even the point of construction.

A factory constructor looks like this:

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;
  }
}

Here, Point.zero is a (named) factory constructor. Factory constructors let you abstract instantiation. You invoke them like a regular constructor, but they don't automatically generate a new instance of the object. Instead, you're free to do whatever you want in the body of the constructor. Here, every time you do:

new Point.zero();

You will get the same cached _zero object, even though you're using new each time because they factory constructor always returns the same one. They have a couple of uses:

  1. Returning previously cached objects like we're doing here.
  2. Returning a subclass. This is kind of like a factory class for a interface. You may have a class that you can new but under certain circumstances you may actually want to return a subclass of it in order to specialize its behavior. Factory constructors let you do that without having to change the callsite.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文