Estas son las conclusiones de mi propia investigación en profundidad:
Ampliación de la clase Clase parece ser intrínsecamente imposible, aunque esto no está bien documentada en cualquier lugar que aún no he visto.A partir de mi investigación, ahora estoy convencido de que la clase Class no incluye todas las cualidades que tienen las otras clases de nivel superior, aunque se dice que todas ellas se extienden desde la clase Object.
Aún más frustrante es el hecho de que la subclasificación de diferentes clases de nivel superior dará lugar a varios mensajes de error diferentes, lo que hace que sea un tanto difícil saber qué problemas están en juego. Para empezar con un ejemplo sencillo, si se intenta subclase muchos de los tipos de datos primitivos de ActionScript (int, uint Número, cadena, booleano, etc.), se obtiene el siguiente compilador de error:
1016: Base class is final.
Esto tiene sentido , porque mirando la documentación para cualquiera de estas clases revela que son de hecho final:
Package Top Level
Class public final class Boolean
Inheritance Boolean -> Object
la palabra clave final, por supuesto, significa que otra clase no se puede extender la clase marcada como definitiva. Ahora, para un ejemplo más complicado, veamos una extensión de la clase de Función. La clase de función no es definitiva, de acuerdo con los documentos. Como no es final, ¿significa que podemos extender la clase de Función para crear nuestros propios objetos de función especializados ? Aquí es una definición:
class MyFunction extends Function { /*...*/ }
.. y luego en el tiempo de ejecución :
VerifyError: Error #1103: Class ::MyFunction cannot extend final base class.
comparar esto con el error tipo de datos primitivo anteriormente. Ese error ocurrió en el momento de la compilación, ya que la clase primitiva heredada se marcó como definitiva. La clase de función es no marcada como definitiva, pero la clase todavía se comporta como si fuera, solo en tiempo de ejecución.
Ahora, llegamos a la cuestión de la pregunta principal: ampliar la clase Class. Al igual que con la clase Function, la clase Class no es definitiva. Además, la clase Class es dinámica, lo que significa que se pueden agregar nuevas propiedades a un objeto Class en tiempo de ejecución.
Como una interesante nota al margen: La clase de función también es dinámica, y creo que esta parte de lo que permite el soporte continuo de los viejos mecanismos de herencia prototípica presentes en el dialecto ECMAscript. En este dialecto, las funciones se utilizan como clases de un tipo (bueno, prototipos), y la capacidad de las funciones para agregar propiedades en el tiempo de ejecución es parte del poder de la herencia prototípica.
Ahora, entiendo que las propiedades de un objeto Class son las mismas que las propiedades estáticas disponibles para cualquier instancia de esa clase. Por lo tanto, debe tener sentido lógico que alguien desee manipular un objeto Class en tiempo de ejecución, lo que le permite cambiar el comportamiento de esa clase y sus instancias. Que la clase Class sea dinámica refuerza esta noción.
Dado que la clase Class no es definitiva, tenía curiosidad por ver si se puede ampliar la clase Class, crear su propia especialización del modelo Class y trabajar en algún lugar del dominio meta-language. Dejaré para otro día la discusión de por qué alguien querría hacer esto, y qué poder hipotéticamente permitiría. Ahora, para el ejemplo final, extendamos la clase Class. Aquí hay una definición:
// the definition causes no errors on its own, even though the compiler "sees" it
class MyClass extends Class { /*...*/ }
/* elsewhere */
MyClass; // the only mention of MyClass beyond the definition
..y luego en el tiempo de ejecución :
verify global$init()
stack:
scope:
locals: global
/* snip about 120 lines */
46:getlex 34
stack: global Class$?
scope: global Object$ Class$
locals: global
48:newclass MyClass$cinit()
VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds.
at global$init()
Santo StackTrace! El VerifyError
está reservado para datos SWF malformados. En función de lo que pude encontrar, esta es también la forma en que un "error" en Flash Player tiende a manifestarse. En cualquier caso, esto va un poco más allá de un error común de ActionScript.
En este punto, se vuelve bastante difícil de entender exactamente lo que está sucediendo, pero esto es lo que he podido deducir hasta ahora.
VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds.
I (por error, ver más abajo comentario) creen que "ABC" es sinónimo de clase base abstracta, que es un término que se aplica a las clases que no se pueden crear instancias, sólo se extendió. Sin embargo, el error aterrador anterior no viene en un momento de creación de instancias, sino en el primer acceso de la clase de clase MyClass. De hecho, el código del ejemplo, nunca una vez instanciar un objeto MyClass, solo me refiero a la clase MyClass.
Hice algunas pruebas más y descubrí que los objetos de clase no parecen tener constructores, al menos, del tipo que normalmente provienen de las subclases de objeto. Simplemente escribiendo new Class();
en cualquier parte de su código demostrará muy bien este hecho, pero puede investigar esto más a fondo inspeccionando la propiedad .constructor
y con otros trucos. Como resultado de esto, las instancias de la clase Class son, en el mejor de los casos, objetos de segunda clase, ya que no se pueden construir en tiempo de ejecución.
Al principio sospeché que esta era la causa exacta de mi desagradable VerifyError
. Sin embargo, ahora creo que hay muchos otros elementos en una clase, invisibles para nuestro código ActionScript, que pueden existir o no dentro de la clase Class, la clase Function u otros lugares curiosos. Ciertamente, cuando Flash Player intenta acceder a uno de los necesarios para la extensión de una clase base, y no existe (ya que Class es posiblemente un ABC, por lo que faltan ciertos elementos presentes en una clase normal), uno podría esperar para ver un fuera de límites VerifyError
.
En resumen, la ampliación de la clase Class parece ser imposible en este momento. Parece que la clase Class no incluye todas las cualidades que la mayoría de las otras clases de nivel superior heredan de Object, aunque esto es difícil de probar.
Preferiría ver un resultado de mensaje de error más específico al extender Class, pero por el momento no existe tal cosa. Me encantaría ver que alguna capacidad de metaprogramación regrese a ActionScript. Por ahora, es suficiente saber de manera concluyente que no se puede hacer, al menos, de esta manera.
La pregunta principal es: ¿Es Clase una clase? –
Bueno, en realidad estoy preguntando si puede subclasificar la clase Class, o si eso es un uso indebido del modelo de clase. Ya sé que Class es una clase; aquí está la clase Class livedoc: http://help.adobe.com/en_US/AS3LCR/Flash_10.0/Class.html – ivanreese
a instanceof b // true –