2010-04-10 3 views
5

Я писал систему, которая во время выполнения генерирует некоторые шаблоны, а затем генерирует некоторые объекты на основе этих шаблонов. У меня была идея, что шаблоны могли быть расширениями класса Class, но это привело к некоторым великолепные ошибки:Можно ли расширить класс класса?

VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

Что мне интересно, если подклассов класса даже возможно, если есть, возможно, некоторые случай, когда делать это было бы уместно, а не просто грубое злоупотребление ООП. Я считаю, что это должно быть возможно, так как ActionScript позволяет создавать переменные типа Class. Это использование описано в LiveDocs entry for Class, но я не видел упоминаний о классе подкласса.

Вот псевдокод пример:

class Foo extends Class 

var A:Foo = new Foo(); // A is a class 
trace(A is Class); // true, right? 
var b = new A(); // b is an instance of class A 

Я понятия не имею, что тип b будет. Это будет так?

trace(b is A); // true? 

Но тогда, Вы могли бы ввести переменную b ввести A, как и в var b:A = new A();, даже если A не существует до момента исполнения? Я читал, что это невозможно, так как A не статически разрешима, но я делаю свои собственные тесты, чтобы изучить эту возможность.

В конечном счете, целью является создание новых классов во время выполнения, а затем создание экземпляров этих классов.

Подводя итог: можете ли вы подклассы класса класса? Если да, то как вы можете сделать это без ошибок, и каков тип экземпляров класса подкласса Class?

+0

Главный вопрос: Является ли класс классом? – 2010-04-10 18:16:26

+0

Ну, я действительно спрашиваю, можете ли вы подклассифицировать класс класса, или если это неправильное использование модели класса. Я уже знаю, что класс - это класс; вот класс Класс liveoc: http://help.adobe.com/en_US/AS3LCR/Flash_10.0/Class.html – ivanreese

+0

a instanceof b // true – 2010-04-10 20:00:26

ответ

1

Вот результаты моих собственных исследований в углубленном:

Расширение класса Class, кажется, по сути невозможно, хотя это не очень хорошо задокументированы в любом месте, что я еще не видел.Из моего исследования я теперь убежден, что сам класс класса не включает в себя все качества, которые имеют другие классы верхнего уровня, хотя все они говорят, что они распространяются от класса Object.

Дальнейшее разочарование заключается в том, что подклассификация различных классов верхнего уровня приведет к нескольким различным сообщениям об ошибках, что затрудняет определение проблем, которые возникают при игре. Начнем с простого примера, если вы пытаетесь подкласс многих примитивных типов данных ActionScript, (INT, UINT, Number, String, Boolean, и т.д.), вы получите следующий компилятор ошибку:

1016: Base class is final. 

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

Package  Top Level 
Class   public final class Boolean 
Inheritance Boolean -> Object 

окончательное ключевое слово, конечно, означает, что другой класс не может расширить класс, помеченный как окончательного. Теперь для более активного примера рассмотрим расширение класса Function. В соответствии с документами класс функции не является окончательным. Поскольку это не является окончательным, означает ли это, что мы можем расширить класс Function для создания собственных специализированных объектов? Вот определение:

class MyFunction extends Function { /*...*/ } 

.., а затем в выполнения:

VerifyError: Error #1103: Class ::MyFunction cannot extend final base class. 

Сравните это с примитивным типом данных ошибки выше. Эта ошибка произошла во время компиляции, поскольку унаследованный примитивный класс был фактически отмечен как окончательный. Класс Function не отмечен как final, но класс по-прежнему ведет себя так, как если бы он был, только во время выполнения.

Теперь мы остановимся на главном вопросе: расширение класса класса. Как и в классе Function, класс класса не является окончательным. Кроме того, класс класса является динамическим, то есть новые свойства могут быть добавлены к объекту класса во время выполнения.

В качестве интересного примечания: класс Function также является динамическим, и я считаю, что эта часть позволяет продолжить поддержку старых прототипных механизмов наследования, присутствующих на диалекте ECMAscript. На этом диалекте функции используются как классы сортировки (ну, прототипы), а способность функций добавлять свойства во время выполнения является частью силы прототипного наследования.

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

Поскольку класс класса не является окончательным, мне было любопытно узнать, можно ли расширить класс класса, создать собственную специализацию модели класса и работать где-то в области метаязыков. Я оставлю еще на один день дискуссию о том, почему кто-то захочет это сделать, и какую власть он предположительно допустил бы. Теперь для заключительного примера давайте расширим класс Class. Вот определение:

// the definition causes no errors on its own, even though the compiler "sees" it 
class MyClass extends Class { /*...*/ } 

/* elsewhere */ 

MyClass; // the only mention of MyClass beyond the definition 

..а затем в выполнении:

verify global$init() 
        stack: 
        scope: 
        locals: global 

/* snip about 120 lines */ 

    46:getlex 34 
        stack: global Class$? 
        scope: global Object$ Class$ 
        locals: global 
    48:newclass MyClass$cinit() 
VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

    at global$init() 

Святого StackTrace! VerifyError зарезервирован для искаженных данных SWF. Основываясь на том, что я мог найти, это также то, как «ошибка» в Flash Player имеет тенденцию проявляться. В любом случае это немного превышает обычную ошибку ActionScript.

На данный момент довольно сложно понять, что именно происходит, но это то, что я смог вывести до сих пор.

VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

I (ошибочно, смотри ниже комментарий) считают, что «ABC» означает абстрактный базовый класс, который представляет собой термин, применяемый к классам, которые не могут быть созданы только продлен. Однако вышеупомянутая ужасающая ошибка возникает не в момент создания экземпляра, а при первом доступе к подклассу класса MyClass. Фактически, код примера, я ни разу не создавал экземпляр объекта MyClass, я имею в виду только класс MyClass.

Я сделал еще несколько тестов и обнаружил, что объекты класса, по-видимому, не имеют конструкторов, по крайней мере, таких типов, которые обычно поступают из подклассов объектов. Просто введите new Class(); в любом месте вашего кода, это продемонстрирует этот факт, но вы можете изучить это дальше, проверив свойство .constructor и с другими трюками. В результате этого экземпляры класса Class являются лучшими объектами второго класса, так как они не могут быть созданы во время выполнения.

Сначала я подозревал, что это была точная причина моего противного VerifyError. Однако теперь я считаю, что для класса есть много других элементов, невидимых для нашего собственного кода ActionScript, которые могут или не могут существовать в классе класса, классе функций или в других любопытных местах. Конечно, когда Flash Player пытается получить доступ к одному из тех, которые необходимы для расширения базового класса, и он не существует (поскольку класс, возможно, является ABC, таким образом, отсутствуют некоторые элементы, присутствующие в нормальном классе), вполне можно ожидать увидеть за пределами VerifyError.

Таким образом, расширение класса класса в настоящее время представляется невозможным. Казалось бы, класс Class не включает в себя все качества, которые большинство других классов верхнего уровня наследуют от Object, хотя это трудно проверить.

Я бы предпочел увидеть более конкретное сообщение об ошибке из расширения класса, но на данный момент такой вещи нет. Я хотел бы увидеть, что некоторые возможности метапрограммирования возвращаются к ActionScript. На данный момент достаточно хорошо понять, что это невозможно сделать, по крайней мере, таким образом.

+0

ABC в данном случае обозначает ActionScript Bytecode. Эта трассировка, которую вы отправили, - это ABC, выполняемая при вызове исключения, причем последняя строка является кодом операции «новый класс». Если вы проверите документы AVM для newclass (http://www.adobe.com/devnet/actionscript/articles/avm2overview.pdf), вы увидите, что базовые классы (в данном случае Class и Object) должны быть включены стек и их статические инициализаторы будут запущены. Возможно, это корень исключения. Класс не имеет статического инициализатора, и поиск его вызывает чтение вне пределов. – tclem

+0

tclem, спасибо за ссылку. Я понятия не имел, что они предоставили такой документ. Я прочитаю его и пересмотрю свой пост тем, что я узнаю. – ivanreese

5

Из жилого в первом абзаце это указано Every Class object is an instance of the Class class. Следовательно, было бы ошибкой продлить класс, поскольку любой объект класса уже является классом.

Вы сказали a system that generates some templates, and then generates some objects based on those templates. Похоже, что вы действительно пытаетесь создать интерфейс.

Интерфейс должен использоваться, если ваш шаблон не предусматривает никакой реализации. То есть вы объявляете кучу полей и методов, но не выполняете реализацию этих методов. Вы бы объявить такой класс следующим образом:

public interface Foo { 
    function bar:void; 
} 

Теперь, чтобы создать класс, который реализует этот интерфейс, вы просто сделать следующее.

public class MyClass implements Foo { 
    function bar:void { 
     ..... implementation goes here ..... 
    } 
} 

Класс может реализовывать несколько интерфейсов, хотя он может распространяться только на один класс.

Если, однако, вы хотите предоставить любую реализацию в своем классе шаблонов, то, скорее всего, вам лучше всего создать класс, который имеет общие черты, которые имеют подклассы, и просто использует обычное старое наследование.

Надеюсь, это поможет.

+0

Мэтт, спасибо за ваш ответ. Я немного уточню этот вопрос, так как вы рассмотрели этот вопрос, поскольку я представил его довольно хорошо, но теперь я понимаю, что не полностью уточнил, какое использование я имею в виду. Интерфейсы не будут работать в этом случае, поскольку интерфейс в ActionScript не является само по себе (хотя это тип данных, согласно документам), это конструкция, используемая для стандартизации открытого интерфейса класса. Я ищу объект-представление класса, который можно динамически манипулировать и создавать экземпляры во время выполнения. – ivanreese

+0

Кроме того, re: ваш первый абзац: почему это ошибка? Я не вижу этого, хотя кажется, что я его переживаю (см .: ABC Error). Если каждый объект типа Class является экземпляром класса Class, почему я не могу создать подкласс класса Class, а затем создавать экземпляры подкласса, так как они все еще будут иметь класс класса в своей родословной? – ivanreese

+0

Наконец, я проголосую за ваш ответ, как только у меня будет 15 представителей. Поскольку это мой первый вопрос когда-либо, и сегодня мой первый день активно публикуется на сайте (хотя я был долгое время поклонником и читателем), это займет у меня немного, прежде чем я буду полностью на борту и в состоянии участвовать в полной мере. Еще раз спасибо. – ivanreese

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