Дострочное пересдача экзамена
|
Создание и модификация объектов
Генетическое программирование объекта при помощи прототипа
Когда рождается ребенок, мы ожидаем, что у него будет голова, два глаза, два уха, две ноги и так далее. Все это мы ожидаем увидеть у всех детей, поскольку эти признаки жестко зашиты в нашем генетическом коде. То же самое применимо и к объектам, создаваемым ActionScript. При создании экземпляров нашего класса Person имена и возраст могут варьироваться, но прочие характеристики являются общими для всех экземпляров. Давайте, рассуждая таким образом, внесем еще изменения в описание нашего класса Person.
- Откройте файл class1.fla из папки Lesson06/Assets. Откройте панель Действия, выделите кадр 1. Измените описание класса Person следующим образом:
_global.Person = function(name, age){ this.name = name; this.age = age; } Person.prototype.legs = 2; Person.prototype.head = new Object() Person.prototype.head.eyes = 2; Person.prototype.head.memories = new Array();
Здесь, как видите, мы вынесли некоторые свойства за пределы формального описания класса и присоединили их к объекту-прототипу класса Person – специальному объекту, связанному с классом. Этот объект (создаваемый автоматически, когда описывается новый класс) содержит свойства и значения, универсальные для данного класса. Можете считать, что этот объект – вроде как прицеп к описанию класса, специальное приложение.
Примечание Все классы объектов, включая встроенные в ActionScript, имеют ассоциированный с ними объект-прототип. В этом уроке мы бегло ознакомим вас с объектами-прототипами этих классов.
Объект-прототип класса не будет содержать никаких значений, пока мы их не запрограммируем – поэтому мы и добавили этому объекту три свойства (и присвоили им значения) сразу после описания класса. Эти свойства объекта-прототипа автоматически наследуются всеми экземплярами данного класса, и их значения доступны точно так же. Очень важно уяснить принцип работы объекта-прототипа, поэтому давайте об этом поговорим.
Когда создается новый экземпляр класса Person, описание класса придает ему два свойства – name и age. Вот иллюстрация доступа к одному из этих свойств:
myVariable = person1.age;
Первым делом ActionScript смотрит в person1, чтобы определить, имеется ли у этого экземпляра свойство age. Видя, что оно есть (это свойство было присоединено при активации экземпляра – проходе через описание класса), ActionScript присваивает значение этого свойства переменной myVariable. Теперь давайте рассмотрим такую строку скрипта:
myVariable = person1.legs;
Вы помните, что описание класса Person теперь не включает свойства legs, тем не менее, myVariable получит значение 2. Дело вот в чем: при таком сценарии ActionScript сначала смотрит в экземпляр, пытаясь найти у него свойство legs. Не найдя такого, ActionScript говорит себе: "Ладно, ведь person1 у нас – экземпляр класса Person. Раз я не нашел свойства legs у этого экземпляра, надо посмотреть в объекте Person.prototype, может, там есть такое". Тут ActionScript обнаруживает, что Person.prototype.legs существует и имеет значение 2, стало быть, и person1.legs равно 2. Это значение ActionScript присваивает переменной myVariable.
Итак, ActionScript всегда ищет свойство сначала на уровне экземпляра (термин уровень экземпляра мы вскоре разъясним). Если свойство нашлось – поиск прекращается, если нет – продолжается в объекте-прототипе класса, к которому принадлежит экземпляр. Считайте, что объект-прототип класса – это зеркало. Все его свойства отражаются на каждый экземпляр данного класса. Хотя экземпляр на самом деле не содержит таких свойств, ActionScript будет считать, что они есть.
Вы можете подумать: ведь все эти свойства прекрасно работали, будучи частью описания класса (как в предыдущем упражнении); зачем же морочить голову еще и прототипами? Дело в том, что объект-прототип позволяет распространять изменения на весь класс – то есть на все экземпляры этого класса. Если изменить значение какого-либо свойства в объекте-прототипе класса, то все экземпляры этого класса – вновь создаваемые и существующие – унаследуют это новое значение (за одним исключением, о котором чуть позже). Чтобы вы еще лучше усвоили эту концепцию, давайте немного поупражняемся.
- Добавьте в конец скрипта следующие строки:
person1 = new Person ("Justin", 16); person2 = new Person ("Derek", 29); trace (person1.legs); trace (person2.legs);
Первые две строки создают два экземпляра объекта Person. Действия trace выводят значение свойства legs для каждого экземпляра.
- Командой Управление > Проверить фильм (Control > Test Movie) запустите тест проекта.
Откроется окно Выход (Output), и в нем отобразится следующее:
2 2
Как видите, person1 и person2 имеют одинаковое значение свойства legs. Мы можем сделать изменение для всего класса (то есть изменить значение для всех экземпляров), поменяв значение свойства legs объекта Person.prototype. Давайте так и сделаем.
- Закройте тестовый фильм и вернитесь в среду разработки. Выделив кадр 1, поменяйте значение Person.prototype.legs с 2 на 5. Затем командой Управление > Проверить фильм вновь запустите тест проекта.
Откроется окно Выход (Output), и в нем отобразится следующее:
5 5
Как видите, простое изменение одного значения в объекте Person.prototype привело к тому, что и person1, и person2 получили новое значение свойства legs. Если бы у нас было сто экземпляров, все они получили бы это новое значение. Добавление, удаление или изменение свойств объекта-прототипа класса немедленно отражаются на всех экземплярах этого класса (единственное исключение, о котором мы уже упоминали, мы обсудим в следующем разделе).
Итак, экземпляры объекта могут иметь как уникальные свойства, так и универсальные (одинаковые для всех экземпляров данного класса). Например, мы все имеем разные имена и возраст (свойства, заложенные в описании класса), но также мы имеем некоторые общие признаки – две ноги, голова, и на ней два глаза (свойства, устанавливаемые объектом-прототипом).
- Закройте тестовый фильм и вернитесь в среду разработки. Выделив кадр 1, верните Person.prototype.legs значение 2. Сохраните свою работу как class2.fla.
Мы продолжим работу с этим файлом в следующем упражнении.