2009-11-07 17 views
5

En ActionScript 3, se puede determinar si el objeto O es de clase C o de una clase que se extiende o se implementa la clase C (directa o indirectamente) usando ...¿Cómo probar correctamente la herencia de clase en ActionScript 3?

if (O is C) { 
    ... 
} 

Lo que quiero hacer es probar si la clase CC extiende o implementa la clase C (directa o indirectamente), sin tener que instanciar un objeto.

En Java, se usaría ...

if (C.isAssignableFrom (CC)) { 
    ... 
} 

http://java.sun.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)

¿Qué hay de ActionScript 3?

Gracias!

Respuesta

3

Puede llamar describeType() en CC directamente. No tienes que crear una instancia del objeto.

var typeXML:XML = describeType(CC); 
if(typeXML.factory.extendsClass.(@type=="C").length() > 0) 
{ 
... 

No es tan limpio como me gustaría pero no puedo encontrar nada mejor.

(a través de Amarghosh: [http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#describeType()][1])

+1

Genial, gracias. Viniendo de la rica API Java 6, me encuentro reinventando la rueda todo el tiempo con Flash/Flex, grrr ;-). – jmdecombe

+0

Esto es bueno pero relativamente lento. Si solo haces esto de vez en cuando, estás bien. De lo contrario, considere 'isPrototypeOf()'. –

1

creo, que tendrá que analizar manualmente a través del objeto XML devuelto por flash.utils.describeType

+0

No hay forma de determinar el tipo simplemente mirando la clase (excepto mediante el uso de 'flash.utils.describeType'). Solo puede hacer esto creando una instancia del objeto primero. –

+0

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#describeType() – Amarghosh

+0

* paréntesis son parte del enlace – Amarghosh

0

Alternativamente, si se utiliza as3commons-reflect paquete (que es muy, muy útil, por cierto), puede llamar a:

ClassUtils.getImplementedInterfaces(CC) 
0

Worth incluyendo el Spicelib reflection biblioteca como otra alternativa. Específicamente ClassInfo.isType.

Comprueba si la clase o interfaz representado por esta instancia ClassInfo es una subclase o subinterfaz de la clase especificada

ClassInfo.forClass(A).isType(B); 
0

Aquí hay un truco que acabo de encontrar. No estoy seguro de qué tan sólido es, pero funciona para mí.

var child:Child = getChild() as Parent; 
if(child != null) { 
    ... 
} 
-1

describeType() es muy lento para hablar, computacionalmente. Si necesita determinar la cadena de herencia de las clases desinstaladas, considere usar Class.prototype y prototype.isPrototypeOf(). Esto le permite verificar la herencia y la igualdad si todo lo que tiene son las propias Clases (a diferencia de un objeto que es una instancia de esa Clase).

Si solo tiene una representación en cadena del nombre de la clase (a diferencia de la propia Clase), debe convertirla en una Clase adecuada primero, utilizando flash.utils.getDefinitionByName() suponiendo que al menos ha declarado la clase en algún lugar de su código . Si la clase solo existe en alguna parte de una Biblioteca SWF cargada, es posible que deba usar algo como ApplicationDomain.currentDomain.getDefinitionByName() o contextLoader.currentDomain.getDefinitionByName().

Aquí hay un ejemplo de trabajo que acepta Classes o String class names y verifica si el primero pertenece a la cadena de herencia del segundo.El argumento adicional le permite decidir si desea devolver falso si las dos clases son idénticas en lugar de la primera extendiendo la segunda.

/** 
* Determines whether the childClass is in the inheritance chain of the parentClass. Both classes must be declared 
* within the current ApplicationDomain for this to work. 
* 
* @param childClass 
* @param parentClass 
* @param mustBeChild 
*/ 
public static function inheritsFrom(childClass:*, parentClass:*, mustBeChild:Boolean = false) { 
    var child:Class, 
     parent:Class; 

    if (childClass is Class) { 
     child = childClass; 
    } else if (childClass is String){ 
     child = getDefinitionByName(childClass) as Class; 
    } 

    if (! child) { 
     throw new ArgumentError("childClass must be a valid class name or a Class"); 
    } 

    if (parentClass is Class) { 
     parent = parentClass; 
    } else if (parentClass is String){ 
     parent = getDefinitionByName(parentClass) as Class; 
    } 

    if (! parent) { 
     throw new ArgumentError("parentClass must be a valid class name or a Class"); 
    } 

    if (parent.prototype.isPrototypeOf(child.prototype)) { 
     return true; 
    } else { 
     if (mustBeChild) { 
      return false; 
     } else { 
      if (parent.prototype === child.prototype) { 
       return true; 
      } 
     } 
    } 

    return false; 
}