| « Поставить закладку » « Сделать стартовой » | |||
|
|||
|
Упаковываем классы, используя __proto__
Вы, должно быть, припоминаете, что в главе Прототипы мы, рассматривая модель пакета из трех оконных стекол, подробно разобрались лишь с первыми двумя. Как вы уже догадались, мы вплотную подошли к тому, чтобы добавить третий слой в нашу модель (ох!). Однако перед этим нам просто необходимо основательно поковыряться во внутренностях экземпляра класса. Итак, когда объект-экземпляр запрашивает некоторое свойство, не имея его при
этом в наличии, автоматически проверяется прототип его конструктора (прототип
класса, который его создал). Даже если и прототип не содержит нужных данных,
история на этом не заканчивается. Этот самый прототип, являясь полноправным
объектом, уж будьте уверены, проверит прототип класса, который создал его -
Object. Короче говоря, он проверит Обратимся к очередной метафоре. Представьте себе, что владелец дома начинает
требовать с вас плату за жилье. И у вас нет ни копейки (вполне возможно, что это
и представлять не надо). Ваши действия? Скорее всего, обычный человек обратится
за помощью к объекту (объектам), которые его создали - к родителям. Вы точно
знаете, что собираетесь расплатиться именно деньгами, взятыми у родителей (вряд
ли хозяин квартиры согласится принять в уплату самих родителей), поэтому вы и
просите их порыться в закромах (в прототипе). Что они сделают, окажись, как и
вы, в затруднительном положении? Очень может быть, что, после коротких
переговоров, посоветуют вам обратиться к объектам, которые создали их - к вашим
бабушкам и дедушкам. Забыв на время о том, что ничто не вечно (а также об
инфляции), мы сможем представить себе картину, где вы от бабушек-дедушек идете к
прабабушкам-прадедушкам, от них - к пра-пра-бабушкам-дедушкам и т.д. И так будет
продолжаться до тех пор, пока вы либо не найдете нужную сумму, либо не
доберетесь до Создателя Всего Сущего. В зависимости от того, кто хранитель
последней надежды в системе ваших убеждений, это может быть либо Бог, либо
правительство, либо, в конце-концов, Откуда объекты узнают, к кому обращаться в затруднительном положении? Им об этом рассказывают после того, как они будут созданы. Кто? Конечно, их родители. Что они при этом говорят? Они говорят: "Милый ребенок, запомни хорошенько, что если когда-нибудь в этом холодном и бесприютном мире ты будешь испытывать нужду, знай, что ты не одинок. В первую очередь обращайся к нам и мы постараемся что-нибудь придумать для тебя". Итак, пока мы еще в светлой памяти, давайте хорошенько усвоим, что классы хранят свои свойства в своих прототипах, а это значит, что объекты, не имея некоторых свойств, проверяют их наличие в прототипе класса, которым были созданы. Уф!
Источником недопонимания может быть следующее: объект и Object. Все экземпляры суть объекты, прототипы тоже объекты, классы описывают объекты... многие вещи являются объектами определенного типа, созданные классами этого сорта. Все классы и объекты, которые они создают, выстраиваются в четкую иерархию и во главе ее стоит совсем уж важная персона, которой необходимо имя. - Слушай, Боб, как ты думаешь, ведь никто из нас не наложит в штаны, Вот так его и окрестили Object-ом, с большой буквы "О" (ведь имя класса
всегда начинается с заглавной буквы). Существует множество типов объектов,
некоторые из них являются экземплярами
Для осмысления того, что все вещи произошли от x = new Object();
вы просто-напросто создаете объект самого общего вида (generic) в
ActionScript (см. примечание выше). Класс Когда вы создаете, например, массив, он будет являться объектом класса
У Ну ладно, с этим мы разобрались. Давайте рассмотрим сам механизм того, откуда
объект узнает о направлении поисков. Эти связи совершаются при помощи
SubClass.prototype.__proto__ = SuperClass.prototype;
Запомните, мы связываем не сами классы, но их прототипы. Классы лишь описывают объекты, прототипы же содержат все необходимые свойства. Еще одна вещь, которую необходимо знать: Вау, пора привести пример! Давайте начнем с нескольких не связанных между собой классов, а сделать это нужно (зачем - поймем далее). Допустим у нас есть Собака (Dog), Кот (Cat) и Хомяк (Hamster):
// Dog Class Dog = function( name ) { this.name = name; } Dog.prototype.legs = 4; Dog.prototype.price = 10; Dog.prototype.pet = true; // Cat Class Cat = function( name ) { this.name = name; } Cat.prototype.legs = 4; Cat.prototype.price = 5; Cat.prototype.pet = true; // Hamster Class Hamster = function( name ) { this.name = name; } Hamster.prototype.legs = 4; Hamster.prototype.price = 15; Hamster.prototype.pet = true; Как видите, здесь присутствуют нежелательные повторения, делающие программу менее гибкой. Что будет, если к оговоренным имени (name), количеству лап (legs), цены (price) и отношению хозяев к своей зверюшке (pet) мы захотим добавить новую категорию, возраст, скажем? Нам бы пришлось забивать его отдельно для каждого зверька, а это неправильно. Мало того, что возрастает объем программы, это в дальнейшем чревато всякими путаницами, ошибками и прочими багами. Что же делать? А давайте посмотрим на код. Решением может являться создание нового надкласса (superClass) с именем, допустим, "Pet" (Любимец). Всех зверюшек (вы можете добавить своих) породим от этого класса и в него же засунем описание всех этих звериных свойств - имя, количество лап, цену и флажок любим/нелюбим
Последнее, что необходимо сделать, это развернуть прототипы Dog.prototype.__proto__ = Pet.prototype; Cat.prototype.__proto__ = Pet.prototype; Hamster.prototype.__proto__ = Pet.prototype; Итак, вооружившись всем этим, приступим.
// Pet class Pet = function( name ) { this.name = name; } Pet.prototype.legs = 4; Pet.prototype.pet = true; // Dog class Dog = function( name ){ } Dog.prototype.__proto__ = Pet.prototype; Dog.prototype.price = 10; // Cat class Cat = function( name ){ } Cat.prototype.__proto__ = Pet.prototype; Cat.prototype.price = 5; // Hamster class Hamster = function( name ){ } Hamster.prototype.__proto__ = Pet.prototype; Hamster.prototype.price = 15; Оставим на время наши попытки и убедимся, что это работает (на самом деле это еще не работает, вы можете заметить проблему?). rover = new Dog( "Rover" ); fluffy = new Cat( "Fluffy" ); ratboy = new Hamster( "Rat-Boy" ); for(var i in rover){ trace( i + ": " + rover[i] ) } /* output pet: true legs: 4 price: 10 */ for(var i in fluffy){ trace( i + ": " + fluffy[i] ) } /* output pet: true legs: 4 price: 5 */ for(var i in ratboy){ trace( i + ": " + ratboy[i] ) } /* output pet: true legs: 4 price: 15 */ Свойство Проблема в том, что свойство Когда программа не работает так, как вам хотелось бы, лучшее, что вы можете сделать - это устранить проблему. Это всегда работает для простейших программ в несколько строчек. Хорошо, как ее устранить: Несмотря на то, что наши экземпляры наследуют свойства от разных уровней цепочки, запускается только младший конструктор. ... и решается проблема парой строчек кода: Pet = function( name ) { this.name = name; } Dog = function( name ){ } Dog.prototype.__proto__ = Pet.prototype; rover = new Dog( "Rover" ); // test trace(rover.name); // undefined Сначала можно просто попытаться запускать конструктор Pet каждый раз, когда создается экземпляр Dog, просто вызывая его из конструктора Dog, правильно? Пока аплодисменты не стали слишком оглушительными, необходимо успеть сказать, что это не работает. Для понимания этого необходимо быть очень внимательными и осторожными, возможно, вновь представить себе объекты в виде черных ящиков. Вот как это может выглядеть: Dog = function( name ) { Pet( name ); } Dog.prototype.__proto__ = Pet.prototype; rover = new Dog( "Rover" );
Мы знаем, что
Pet = function( name ) { this.name = name; } Dog = function( name ) { // делаем Pet методом экземпляра this.$_base = Pet; // запускаем Pet отсюда, т.к. "this" // эквивалентен экземпляру this.$_base( name ); // освобождаемся от внедренного метода! delete this.$_base; } Dog.prototype.__proto__ = Pet.prototype; rover = new Dog( "Rover" ); // проверяем trace(rover.name); // Rover Ну наконец-то работает! Есть несколько вещей, которые нужно знать. Первое и
главное: весь блок кода, касающийся Вторая проблема состоит в том, что на данный момент у вас существуют две ссылки на родительские классы. Программирую в ООП вы часто будете тасовать классы в поисках лучшего решения и у вас всегда есть шанс что-то упустить. Если у вас прототип связан с одним классом, а конструктор с другим - да поможет вам Бог. Очень трудно отловить баг. ООП требует представления программ в виде блоков и поскольку класс тоже является отдельным блоком, он должен иметь единственную цепочку наследования (как, впрочем, и в других языках ООП). Возможно, это и не кажется чем-то важным, однако, когда программа возрастает, вышесказанное становится непомерной ношей. Последнее замечание носит скорее косметический характер. Может быть это и тяжело, но вы не должны строить свои решения на примере одного и того же кода. Конечно, большинство людей в конце-концов создали свои наработки в этой области и пользуются ими, чтобы автоматизировать процесс. Когда-нибудь и вы обзаведетесь своими излюбленными приемами. Ну а перед этим нужно пробовать, искать, изучать... Рубрика: Flash
Вышел MySQL 5.1.30, первый стабильный рели....
После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:
Подробнее... |
Рубрика: MySQL
| Добавлено: 28.11.2008
Тестирование параллельных программ.
Тестирование параллельного программного обеспечения представляет собой более сложную задачу по сравнению с тестированием последовательной программы. Программист должен знать о подводных камнях при тестировании параллельного кода, имеющихся методологиях и инструментарии.
Подробнее... |
Рубрика: Тестирование
| Добавлено: 28.11.2008
Архитектура AMD64 (EM64T).
Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.
Подробнее... |
Рубрика: Архитектура AMD
| Добавлено: 27.11.2008
Остальные статьи: |
Цитата дня (все,добавить):
|
Realcoding.NET
© 2003-2008 |
Контакты |
Реклама на сайте
|