2009-11-07 23 views
5

W języku ActionScript 3, można dowiedzieć się, czy obiekt O jest klasy C lub klasy, która rozszerza lub implementuje klasy C (bezpośrednio lub pośrednio) z użyciem ...Jak poprawnie przetestować dziedziczenie klas w ActionScript 3?

if (O is C) { 
    ... 
} 

Co chcę zrobić jest do sprawdzić, czy klasa CC rozszerza lub implementuje klasę C (bezpośrednio lub pośrednio), bez konieczności tworzenia instancji obiektu.

W Javie byłoby użyć ...

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

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

Jak o ActionScript 3?

Dzięki!

Odpowiedz

3

Można zadzwonić describeType (CC) na wprost. Nie musisz tworzyć instancji obiektu.

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

To nie jest tak czyste, jak bym chciał, ale nie mogę znaleźć nic lepszego.

(przez Amarghosh: [http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#describeType()][1])

+1

Świetnie, dzięki. Opierając się na bogatym API Java 6, musiałem cały czas wymyślać kółko za pomocą Flash/Flex, grrr ;-). – jmdecombe

+0

To jest dobre, ale stosunkowo powolne. Jeśli robisz to od czasu do czasu, nic ci nie jest. W przeciwnym razie rozważ "isPrototypeOf()". –

1

myślę, że trzeba będzie ręcznie analizowania przez obiekt XML zwrócony przez flash.utils.describeType

+0

Nie ma sposobu, aby określić typ po prostu patrząc na klasę (z wyjątkiem użycia 'flash.utils.describeType'). Możesz to zrobić tylko przez utworzenie instancji obiektu w pierwszej kolejności. –

+0

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

+0

* nawiasy są częścią łącza – Amarghosh

0

Alternatywnie, jeśli używasz as3commons-reflect pakietu (co jest bardzo przydatne, nawiasem mówiąc), można nazwać:

ClassUtils.getImplementedInterfaces(CC) 
0

Warto w tym Spicelib Biblioteka reflection jako inna alternatywa. W szczególności ClassInfo.isType.

Sprawdza czy klasa lub interfejs reprezentowane przez instancję ClassInfo jest podklasą lub podinterfejsu z określonej klasy

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

Oto Hack Właśnie znalazłem. Nie jestem pewien, jaki jest solidny, ale działa dla mnie.

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

describeType() jest bardzo powolny, mówiąc komputerowo. Jeśli musisz określić łańcuch dziedziczenia nieprzypisanych klas, rozważ użycie opcji Class.prototype i prototype.isPrototypeOf(). To pozwala ci sprawdzić dziedziczenie i równość, jeśli wszystko, co masz, to same Klasy (w przeciwieństwie do obiektu będącego instancją tej Klasy).

Jeśli masz tylko ciąg reprezentujący nazwę klasy (w przeciwieństwie do samej klasy), musisz najpierw przekonwertować ją na właściwą klasę, używając flash.utils.getDefinitionByName(), zakładając, że co najmniej zadeklarowałeś klasę gdzieś w swoim kodzie . Jeśli klasa istnieje tylko w załadowanej bibliotece SWF, być może trzeba użyć czegoś takiego jak ApplicationDomain.currentDomain.getDefinitionByName() lub contextLoader.currentDomain.getDefinitionByName().

Oto działający przykład, który akceptuje albo klasy lub nazwy klasy String i sprawdza, czy pierwszy jest w łańcuchu dziedziczenia drugiego.Dodatkowy argument pozwala ci zdecydować, czy chcesz zwrócić wartość false, jeśli dwie klasy są identyczne, a nie pierwsze, wydłużając drugie.

/** 
* 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; 
}