2009-11-19 3 views
3

Можно ли использовать отражение AS3, чтобы узнать, был ли метод переопределен?AS3 отражение. Как узнать, отменен ли метод?

мне нужен метод, как:

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

    return awesomeLocalVariable; 
} 

Итак, я перехожу в имени метода в виде строки и метод isOverridden дает верно только тогда и только тогда, когда объект имеет метод этого имени, и это переопределен из его первоначальной реализации.

Любая идея о том, как закодировать магию там?

Спасибо.

Edit: В соответствии с просьбой, контекст проблемы:

Я создание основы для создания AS3 игры. Я хочу предоставить «компоненты» для своих игровых объектов, каждый компонент предоставляет функциональность игровому объекту, который он применяет. Компоненты основаны на событиях (onClick, onUpdate, onShapeCollision и т. Д.). Мне нужен этот код в классе Component, поэтому я могу зарегистрировать только те события, которые реализует класс (производный от класса).

Пример Компонент:

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

Рамки должны зарегистрировать метод OnClick как обработчик события для события MouseEvent.CLICK, поскольку он перекрывает реализацию по умолчанию.

Зачем мне нужна реализация по умолчанию? Поскольку я хочу, чтобы классы переопределяли поддерживаемые методы, тогда будет ошибка времени компиляции, если пользователь попытается использовать неподдерживаемое событие.

Это имеет смысл?

+0

Зачем вам это нужно? Можете ли вы предоставить какой-то контекст? – jtbandes

+0

Согласовано. Мне интересно посмотреть, какая проблема это решает. –

+0

Надеюсь, это объяснит это. –

ответ

2

Попробуйте. Функция является статической и может использоваться для проверки любого класса или объекта независимо от класса, в котором он реализован. Если вы дадите ему тип, он будет использовать его, если вы дадите ему экземпляр, он получит тип сам по себе. Внутренняя логика - это просто проверить описание данного типа для функции, которую мы ищем, если таковая существует и объявлена ​​классом, она проверит, существует ли метод в родительском. И если оба существуют, наслаждайтесь, значит, оно переопределено.

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

И только в случае, если это необходимо, импорт требуется для его работы:

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

И использовать его:

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

Отлично, дайте мне попробовать. –

+0

Прочитав снова контекст проблемы, мне пришло в голову, что решение вашей проблемы может быть еще проще. Если вы уже уверены в иерархии своего класса (вы знаете, что он расширяет ваш класс компонентов), вы можете просто искать в описании типа для тех методов, которые вы хотите, и если они «@declaredBy» того же класса, это означает, что они переопределены. – LopSae

0

Если вы задаете внутри одного объекта вы можете

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

Если нет, попробуйте использовать describeType. Проверьте, есть ли метод с именем и проверьте атрибут «declareBy». Вуаля!

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

К сожалению, я в середине перехода от CS3 к Flash Builder поэтому сейчас я не могу гарантировать, мои идеи работают правильно. Но я вернусь.

+0

Я пробовал это раньше, но учтите, что не имеет значения, является ли класс прямым или непрямым дочерним элементом базового класса Component. –

Смежные вопросы