tutorial online method dartlang interface dart

interface - online - ¿Por qué se puede crear una instancia de la interfaz de lista incorporada de Dart?



dart tutorial (2)

Aviso: esta pregunta es obsoleta; la sintaxis de declaración de interface ha sido eliminada de Dart:

Por lo que he podido decir, es imposible crear una interfaz de Dart . Si simplemente intento construir una new MyInterface() , con o sin un constructor definido, new MyInterface() un error en tiempo de ejecución ( pruébelo ):

NoSuchMethodException - receiver: '''' function name: ''MyInterface$$Factory'' arguments: []]

interface MyInterface {}

interface MyInterface { MyInterface(); }

Si trato de utilizar un constructor de fábrica en su lugar, devolviendo una instancia de una implementación, obtengo un error en tiempo de compilación ( pruébelo ):

SyntaxError: factory members are not allowed in interfaces

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

Sin embargo, esto parece estar en desacuerdo con la realidad de que List<E> 1 en la biblioteca principal de Dart es una interfaz 2 , sin embargo, tiene varios constructores y se puede crear una instancia. Por ejemplo, esto funciona bien ( pruébalo ):

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

¿Por qué se pueden crear instancias de la List y muchas otras interfaces integradas? ¿Hay algún método que omití o solo reciben tratamiento especial como tipos incorporados?

1 Dart: Bibliotecas: corelib: lista de interfaz <E>
2 "Gran parte de la biblioteca de Dart Core se define en términos de interfaces". 3
3 Dart: Tutorial: Interfaces


Dart usa la factory para dos cosas diferentes: clases de fábrica y constructores de fábrica. Una clase de fábrica se ve así:

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

Lo que hace es que te permite definir constructores en una interfaz. Cuando los invocas haciendo una new List() (o cualquiera que sea tu interfaz), sabe cómo crear una instancia ConcreteList porque esa es la clase de fábrica que has especificado para esa interfaz.

Esto le brinda una manera de encapsular por completo un tipo concreto detrás de una interfaz, incluido el punto de construcción.

Un constructor de fábrica se ve así:

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

Aquí, Point.zero es un constructor de fábrica (nombrado). Los constructores de fábrica le permiten abstraer instancias. Los invocas como un constructor normal, pero no generan automáticamente una nueva instancia del objeto. En cambio, puedes hacer lo que quieras en el cuerpo del constructor. Aquí, cada vez que lo haces:

new Point.zero();

Obtendrá el mismo objeto _zero almacenado en la _zero caché, aunque esté usando new cada vez, ya que el constructor de fábrica siempre devuelve el mismo. Tienen un par de usos:

  1. Devolver objetos previamente en caché como lo estamos haciendo aquí.
  2. Devolviendo una subclase. Esto es como una clase de fábrica para una interfaz. Puede tener una clase que puede new pero en determinadas circunstancias puede que desee devolver una subclase para especializar su comportamiento. Los constructores de fábrica le permiten hacer eso sin tener que cambiar el callsite.

La sintaxis para definir una interfaz es:

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

Tenga en cuenta que la factorySpecification debe venir antes que el cuerpo de la interfaz en lugar de dentro de ella.

Así que así es como lo escribes:

interface MyInterface default MyImplementation { } class MyImplementation implements MyInterface { MyImplementation(); }

O si quiere ir a la definición genérica completa:

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

Editar : para obtener un ejemplo más completo, puede leer el código fuente de la interface List<E> en https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/corelib/src/ list.dart y la class ListFactory<T> asociada class ListFactory<T> source está en https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/runtime/lib/array.dart