2009-11-19 4 views
3

Est-il possible d'utiliser la réflexion AS3 pour savoir si une méthode a été surchargée?Réflexion AS3. Comment savoir si une méthode est surchargée?

je besoin d'une méthode comme:

protected function isOverriden(methodName:string) : bool 
{ 
    //magic here! 
    //... 

    return awesomeLocalVariable; 
} 

Alors, je passe dans le nom de la méthode comme une chaîne et la méthode isOverridden cède vrai que si et seulement si l'objet a une méthode de ce nom et il est substitué de son implémentation d'origine.

Une idée sur la façon de coder la magie là-bas?

Merci.

Edit: Comme demandé, le contexte du problème:

Je construis un cadre pour la création de jeux AS3. Je veux fournir des "composants" pour mes objets de jeu, chaque composant fournit des fonctionnalités à l'objet de jeu auquel il est appliqué. Les composants sont basés sur des événements (onClick, onUpdate, onShapeCollision, etc.) J'ai besoin de ce code dans la classe Component, donc je ne peux enregistrer que les événements implémentés par la classe Component-derived (overrides).

composant Exemple:

public class CTrace extends ScriptComponent 
    { 
      public override function onClick(event:MouseEvent = null):void 
      { 
        trace(Owner.Id); 
      } 
    } 

Le cadre devrait enregistrer la méthode onClick comme le gestionnaire d'événements pour l'événement MouseEvent.CLICK car il remplace l'implémentation par défaut. Pourquoi ai-je besoin de l'implémentation par défaut? Parce que je veux que les classes remplacent les méthodes prises en charge, il y aura donc une erreur de compilation si l'utilisateur essaie d'utiliser un événement non pris en charge.

Est-ce que cela a du sens?

+0

Pourquoi avez-vous besoin? Pouvez-vous fournir un contexte? – jtbandes

+0

D'accord. Je suis intéressé de voir quel problème cela résout. –

+0

J'espère que cela l'explique. –

Répondre

2

Voici un essai. La fonction est statique et peut être utilisée pour vérifier n'importe quelle classe ou objet indépendamment de la classe dans laquelle elle est implémentée. Si vous lui donnez le type, il l'utilisera, si vous lui donnez une instance, il obtiendra le type par lui-même. La logique interne consiste simplement à vérifier la description du type donné pour la fonction que nous recherchons, si elle existe et est déclarée par la classe, elle vérifiera si la méthode existe aussi dans le parent. Et si les deux existent, profitez-en, cela signifie que c'est annulé.

/** 
* Returns true only if the method name given is declared by 
* the source class, and any parent class. 
*/ 
static public function isOverridden(source:*, methodName:String):Boolean { 
    var parentTypeName:String = getQualifiedSuperclassName(source); 
    if (parentTypeName == null) { 
     return false; 
    }//if 

    var typeName:String = getQualifiedClassName(source); 
    var typeDesc:XML = describeType(getDefinitionByName(typeName)); 
    var methodList:XMLList = typeDesc.factory.method.(@name == methodName); 

    if (methodList.length() > 0) { 
     //Method exists 
     var methodData:XML = methodList[0]; 
     if ([email protected] == typeName) { 
      //Method is declared in self 
      var parentTypeDesc:XML = describeType(getDefinitionByName(parentTypeName)); 
      var parentMethodList:XMLList = parentTypeDesc.factory.method.(@name == methodName); 
      return parentMethodList.length() > 0; 
     }//if 
    }//if 

    return false; 
}//isOverridden 

Et juste au cas où il est nécessaire, les importations nécessaires pour que cela fonctionne:

import flash.utils.describeType; 
import flash.utils.getDefinitionByName; 
import flash.utils.getQualifiedClassName; 
import flash.utils.getQualifiedSuperclassName; 

Et pour l'utiliser:

trace(isOverridden(ChildrenClass, "overriddenMethod")); //true 
trace(isOverridden(ChildrenClass, "onlyChildMethod")); //false 
trace(isOverridden(ChildrenClass, "onlyParentMethod")); //false 
+0

Excellent, laissez-moi essayer. –

+0

Après avoir relu le contexte du problème, il m'est apparu que la solution à votre problème pourrait être encore plus simple. Si vous êtes déjà sûr de la hiérarchie de votre classe (vous savez qu'elle étend votre classe de composant), vous pouvez simplement chercher dans la description de type les méthodes que vous voulez, et si elles sont "@declaredBy" la même classe, cela signifie qu'elles sont remplacés. – LopSae

0

Si vous demandez à l'intérieur même objet que vous pouvez

overriden = (this[stringNameOfMethod] instanceOf Function && super[stringNameOfMethod] instanceOf Function); 

Sinon, essayez d'utiliser describeType. Vérifiez s'il existe une méthode avec le nom et vérifiez l'attribut "declaredBy". Voila!

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

Désolé, je suis au milieu d'une migration de CS3 à Flash Builder donc pour l'instant je ne peux pas assurer que mes idées fonctionnent correctement. Mais je serai de retour.

+0

J'ai déjà essayé, mais notez que cela n'a pas d'importance si la classe est un enfant direct ou indirect de la classe de base Component. –

Questions connexes