How to properly test for class inheritance in Acti

2019-06-21 20:52发布

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!

6条回答
干净又极端
2楼-- · 2019-06-21 20:52

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);
查看更多
Deceive 欺骗
3楼-- · 2019-06-21 20:53

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] )

查看更多
走好不送
4楼-- · 2019-06-21 21:00

I think , you will have to manually parse through the XML object returned by flash.utils.describeType

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-06-21 21:08

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;
}
查看更多
放荡不羁爱自由
6楼-- · 2019-06-21 21:12

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) {
    ...
}
查看更多
ら.Afraid
7楼-- · 2019-06-21 21:14

Alternatively, if you use as3commons-reflect package (which is very, very useful, by the way), you can call:

ClassUtils.getImplementedInterfaces(CC)
查看更多
登录 后发表回答