Методы и свойства
До сих пор во всех наших примерах свойства классов принимали простейшие значения, такие как "rover" или 5. Имя класса (Dog, например) назначалось им свойству и прототип становился свойством этого класса (Dog.prototype в нашем случае). В ActionScript мы фактически можем назначить что-нибудь свойству. Это отличает ActionScript от многих других языков (Java, например), так что мы оказываемся перед необходимостью разъяснить, что подразумеваем под "свойством". В Java и С++ существует большая разница между методами и свойствами, чего нет а ActionScript-е. Так что же такое методы?
Метод очень похож на то, что мы обычно понимаем под функцией в программе, с одним отличием, методы всегда привязаны к классу и, как правило, вызываются из объекта-реализации этого класса. Методы призваны модифицировать состояние этого объекта и/или возвращать вычисленные значения. Они не используются для создания нового экземпляра класса. Методы никогда не используют свои прототипы, они не помещают свойства в собственное пространство имен (namespace). Методы не похожи на классы. Это просто программы, принадлежащие классу.
Можно сказать, они "выглядят" как классы. Они тоже созданы при помощи функции, однако они не вызываются при помощи оператора new. Их ключевое слово this ссылается на объект, который вызвал этот метод, никак не на созданный новый. Поскольку они, подобно классам, автоматически не возвращают новый объект, они могут возвращать какое-то значение, даже если оно пустое (void) (хотя это не требование, это просто хороший стиль программирования в более строгих языках). И последнее, методам, как и остальным свойствам классов, для их отличия от этих самых классов, лучше всего давать имена, начинающиеся с прописной буквы. Теперь давайте посмотрим маленький примерчик того, как создаются и вызываются методы, и потом разберемся во всех этих терминах, смысл которых, возможно, потихоньку начал от вас ускользать.
// Класс Dog Dog = function( age ) { this.age = age; this.dogYears = this.calcDogYears( this.age ); } // метод Dog - вычисление возраста в собачьих годах Dog.prototype.calcDogYears = function( age ) { return ( this.age * 6 ); } // метод Dog - у собаки день рождения Dog.prototype.haveBirthday = function( ) { this.age++; this.dogYears = this.calcDogYears( this.age ); trace("С Днем Рождения!") }
// создание экземпляра собаки (Dog) yeller = new Dog( 12 ); trace( yeller.dogYears ); // 72 yeller.haveBirthday( ); // метод выдает "С Днем Рождения!" trace( yeller.dogYears ); // 78
А заметили ли вы, что мы всегда определяем прототипы до того, как создадим экземпляр класса? Flash не может вызывать методы, которые еще не определены, поскольку он считывает и выполняет код в том порядке, как он написан (это все потому, что при загрузке swf файла вы никогда не можете быть уверены в том, загрузился ли определенный кусок кода). Посмотрев на конструктор класса в примере, вы можете углядеть противоречие вышесказанному. Метод calcDogYears вызывается из конструктора до того, как он будет описан в прототипе. Однако конструктор запустится лишь в тот момент, когда будет создан объект "yeller". Когда вы пишете код, вы должны рассматривать класс и его прототип как единый блок и определять их вместе. Методы прототипа обычно определяются после его свойств.
Хотя методы и можно поместить в экземпляр класса, такое происходит редко. Методы по природе своей более статические, чем строки или числа, так что они вероятнее всего останутся отдельным большим классом. Будет, возможно, ситуация, когда вы захотите установить методы во время выполнения, передавая их как аргумент конструктору. Это тот случай, когда вы раз и навсегда откажетесь от этого, окончательно запутавшись в многочисленных операторах if-else. Вскоре мы это разъясним.