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:
Propuesta para eliminar declaraciones de interfaz de Dart
"En Dart, cada clase engendra una interfaz implícita. Ahora que se implementa esta característica, es posible eliminar las declaraciones de interfaz del lenguaje. Las declaraciones de interfaz se reemplazan por clases puramente abstractas".Problema 3972: eliminar la compatibilidad de declaración de interfaz en VM
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:
- Devolver objetos previamente en caché como lo estamos haciendo aquí.
- 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