In ActionScript 3, you can figure out whether object O is of class C or of a class that extends or implements class C (directly or indirectly) using...
if (O is C) {
...
}
What I want to do is to test whether class CC extends or implements class C (directly or indirectly), without having to instantiate an object.
In Java, you would use...
if (C.isAssignableFrom (CC)) {
...
}
http://java.sun.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)
How about ActionScript 3?
Thanks!
You can call describeType() on CC directly. You do not have to instantiate the object.
var typeXML:XML = describeType(CC);
if(typeXML.factory.extendsClass.(@type=="C").length() > 0)
{
...
It's not as clean as I'd like but I can't find anything better.
(via Amarghosh: [http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#describeType()][1] )
I think , you will have to manually parse through the XML object returned by flash.utils.describeType
Alternatively, if you use as3commons-reflect package (which is very, very useful, by the way), you can call:
ClassUtils.getImplementedInterfaces(CC)
Worth including the Spicelib reflection library as another alternative. Specifically ClassInfo.isType.
Checks whether the class or interface
represented by this ClassInfo instance
is a subclass or subinterface of the
specified class
ClassInfo.forClass(A).isType(B);
Here's a hack I just found.
Not sure how solid it is, but it works for me.
var child:Child = getChild() as Parent;
if(child != null) {
...
}
describeType()
is very slow, computationally speaking. If you need to determine the inheritance chain of uninstantiated classes, consider using Class.prototype
and prototype.isPrototypeOf()
. This allows you to check inheritance and equality if all you have are the Classes themselves (as opposed to an object that is an instance of that Class).
If you only have a String representation of the class name (as opposed to the Class itself), then you have to convert that to a proper Class first, using flash.utils.getDefinitionByName()
assuming you have at least declared the class somewhere in your code. If the class only exists somewhere in a loaded SWF Library, you may have to use something like ApplicationDomain.currentDomain.getDefinitionByName()
or contextLoader.currentDomain.getDefinitionByName()
.
Here's a working example that accepts either Classes or String class names and checks whether the first one is in the inheritance chain of the second one. The additional argument allows you to decide whether you want to return false if the two classes are identical rather than the first extending the second.
/**
* 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;
}