12

注意:この質問は廃止されました。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<E>ただし、これは、Dart のコア ライブラリの1がインターフェイス2であるにもかかわらず、いくつかのコンストラクタがあり、インスタンス化できるという現実とは相容れないようです。たとえば、これは問題なく動作します (試してください):

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

Listおよび他の多くの組み込みインターフェイスをインスタンス化できるのはなぜですか? 私が見逃した方法がありますか、それとも組み込み型として特別な扱いを受けているだけですか?


1 Dart: Libraries: corelib: interface List<E>
2 "Dart Core Library の多くは、インターフェースに関して定義されています。" 3
3 Dart: チュートリアル: インターフェイス

4

2 に答える 2

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

編集interface List<E>: より完全な例については 、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にあります

于 2011-10-11T08:27:48.873 に答える
2

Dart は、 factory classesと factory constructorsfactoryの 2 つの異なるものに使用します。ファクトリ クラスは次のようになります。

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、特定の状況下では、その動作を特殊化するために、実際にはそのサブクラスを返したい場合があります。ファクトリ コンストラクターを使用すると、呼び出しサイトを変更せずにそれを行うことができます。
于 2011-10-20T14:29:17.343 に答える