Macromedia Flash 5. Объектно - ориентированное программирование




Extends. Специальное ключевое слово - часть 8


Вторая проблема - проблема форвард-ссылок. Она тоже возникает в коде, подобном вышеприведённому. Как уже упоминалось ранее, файлы SWF не поддерживают форвард-ссылки. Они не скомпилированы и просто не имеют представления о том, что за всем этим может последовать (а ведь это "последующее" часто бывает даже не загружено на тот момент). Таким образом, мы вызываем метод setState ещё до того, как создали его. Совершенно очевидно, что этот путь тупиковый. Если даже вы и определились уже с именами ваших будущих "детей", кто вам сказал, что они станут отзываться на эти имена? Вот так-то вот. Ну а что если мы просто поставим определения свойств перед методами? Тогда всё почти получится. Да, именно "почти", потому что тогда методы не будут иметь доступ к свойствам, которые ещё не определены. Какие ещё есть идеи? Разделить их на части? Или просто запоминать, "кто куда пошёл"? Всё это ни к чему не приведёт.

Итак, пришло время кратко изложить суть накопившихся проблем:

  • Свойства прототипов и методы не имеют доступа друг к другу в момент создания класса, если только не использовать в коде фиксированных ссылок..
  • Прототипы определяются ссылками на классы (в левой части), что затрудняет работу с такими классами.
  • Свойства не могут вызывать методы того же прототипа, если только не запускать их после определения методов, (что всё равно не решает проблему, поскольку даже в этом случае, в силу отсутствия форвард-ссылок, методы не будут иметь доступа ко всем свойствам).

Так как же быть?

Проблема с форвард-ссылками похожа на старый как мир вопрос: "Что было раньше - курица или яйцо?". Мы знаем, что методы нужно определять раньше свойств. Мы так же знаем, что свойства нужно определять раньше методов. К счастью, на этот случай есть маленькая хитрость. Методы действительно должны быть определены первыми, но это не означает, что мы должны запускать их первыми. А вот свойства действительно должны быть обработаны в первую очередь. Вот ещё небольшая, но существенная уловка, прототип, как и любой другой элемент, это не класс, а объект. Мы знаем, что по сути объекты, это экземпляры, созданные из образца. А значит, мы можем создать образец, который будет определять прототип, точно так же, как мы делали в случае с другими экземплярами. Таким образом, все свойства и методы определяются в первую очередь, прежде, чем их вызывают. Если мы создадим такой образец внутри прототипа, то при его вызове ключевое слово this будет приравнено к прототипу класса. Так что все эти свойства и методы будут скопированы в прототип. Огромное преимущество этого способа заключается в том, что ключевое слово this приравнивается к прототипу, пока подготавливаются методы и свойства. Это означает, что свойства будут иметь доступ к методам, а методы в свою очередь будут иметь доступ к свойствам. Чтобы быть уверенным, что методы определяются до того, как свойства их вызывают, можно просто разделить их (методы и свойства) на две группы и первыми запускать методы. Потеряют ли в этом случае методы доступ к свойствам? Нет. Потому, что, как мы помним, методы в это время только определяются, а не запускаются. Таким образом, несмотря на то, что к моменту определения метода, свойство, которое он вызывает, ещё не создано, оно будет создано к тому моменту, как будет вызван метод. А как насчёт экземпляров? Если методы ссылаются на другие свойства в прототипе, не означает ли это, что, когда мы создаём экземпляр данного класса, он будет напрямую ссылаться на прототип? Нет. Потому, что значение слова this изменяется в момент доступа из экземпляра. Будучи вызвано из прототипа класса, оно ссылается на прототип. При вызове метода класса из экземпляра, this будет ссылаться на экземпляр. Красотища!




Содержание  Назад  Вперед