Наследование  ActionScript 

 

 

В объектно-ориентированном программировании термин «наследование»  

обозначает формальное отношение между двумя или более классами, при котором один 

класс заимствует (или наследует) описания переменных и методов другого класса. 

С практической, или технической, точки зрения наследование просто позволяет 

использовать код одного класса в другом классе. 

Однако наследование подразумевает нечто гораздо большее, чем повторное  

использование кода. Оно в равной мере является интеллектуальным и техническим 

инструментом и позволяет программистам концептуально представить группу 

классов в виде иерархических отношений. В биологии наследование  

представляет собой генетический процесс, при котором одно живое существо передает 

по наследству свои характерные черты другому существу. Вам говорят, что вы 

унаследовали глаза матери или нос отца, даже несмотря на то, что вы не похожи 

в точности ни на одного из родителей. В объектно-ориентированном  

программировании наследование имеет похожий смысл. Оно позволяет одному классу 

быть во многом подобным другому классу, но при этом обладать собственными 

уникальными свойствами. 

Изучение этой главы мы начнем с рассмотрения синтаксиса и примеров  

использования наследования. Разобравшись с наследованием с практической точки зрения, 

мы рассмотрим его преимущества и альтернативы. И наконец, мы применим  

наследование к нашей программе по созданию виртуального зоопарка. 

Пример наследования 

Рассмотрим простой абстрактный пример, чтобы получить общее представление 

о том, как работает наследование (примеры практического применения  

наследования будут рассмотрены после того, как мы познакомимся с базовым  

синтаксисом). Существует класс А с одним методом экземпляра m ( ) и одной переменной 

экземпляра v: 

public class A { 

public var v = 10; 

public function m ( ) { 

traceCMethod m( ) was called"); 

Как обычно, мы можем создать экземпляр класса А, вызвать метод m ( ) и  

обратиться к переменной v следующим образом: 

var alnstance = new A( ); 
alnstance.m( ); // Выводит: Method m( ) was called 
trace(alnstance.v); // Выводит: 10 
Пока ничего нового. Теперь добавим второй класс В, который наследует метод m ( ) 
и переменную v класса А. Для создания отношения наследования между классами 
А и В используется ключевое слово extends: 
public class В extends A { 
// Никакие методы и переменные не определены 
Поскольку класс В расширяет (унаследован от) класс А, экземпляры класса В могут 
автоматически использовать метод m ( ) и переменную v (даже несмотря на то, что 
в самом классе В этот метод и переменная не определены): 
var bInstance:B = new B( ); 
blnstance.m( ); // Выводит: Method m( ) was called 
trace(blnstance.v); // Выводит: 10 
При выполнении инструкции bins tance. m ( ) среда Flash проверяет, определен 
ли метод m ( ) в классе В. Не найдя метода m ( ) в классе В, Flash продолжает его 
поиск в суперклассе класса В (то есть в том классе, который расширяется  
классом В). Среда выполнения находит метод m ( ) в классе А и вызывает его над 
переменной blnstance. 
Обратите внимание, что в самом классе В не определены никакие методы или  
переменные. На практике определение класса, не добавляющего ничего нового в  
расширяемый класс, не имеет большого смысла, поэтому, как правило, это делать не 
рекомендуется. В обычном же случае, помимо методов и переменных,  
унаследованных от класса А, класс В определял бы свои собственные методы и/или переменные. 
Иными словами, подкласс на самом деле представляет собой расширенный набор 
возможностей, доступных в его суперклассе. Подкласс обладает всем, что  
доступно в суперклассе, а также дополнительными возможностями. Рассмотрим новую 
версию класса В, унаследовавшего метод m ( ) и переменную v от класса А и  
определяющего свой собственный метод п ( ): 
public class В extends A { 
public function n ( ) { 
trace("Method n( ) was called"): 
Теперь экземпляры класса В могут использовать все методы и переменные не  
только класса В, но и его суперкласса А: 
var blnstance = new B( ); 
// Вызов унаследованного метода, определенного в классе А 
blnstance.m( ); // Выводит: Method m( ) was called 
// Вызов метода, определенного в классе В 
blnstance.n( ); // Выводит: Method n( ) was called 
// Обращение к унаследованной переменной 
trace(blnstance.v); // Выводит: 10 
В данном случае говорят, что класс В специализирует класс А. Класс В использует 
возможности класса А в качестве своей основы, добавляя свои собственные  
возможности или даже — как мы увидим далее — перекрывая возможности класса 
А измененными для собственных нужд версиями. Таким образом, в отношении 
наследования между двумя классами расширяемый класс (в нашем случае А)  
называется базовым, а расширяющий класс (в нашем случае В) — производным. Иногда 
для обозначения базового и производного классов также используются понятия 
«предок» и «потомок» соответственно. 
Наследование может (а зачастую так и происходит) включать больше чем два 
класса. Например, даже несмотря на то, что класс В унаследован от класса А, класс 
В может стать базовым для другого класса. Следующий код демонстрирует третий 
класс С, который расширяет класс В, а также определяет новый метод о ( ). Класс 
С может использовать все методы и переменные, определенные в нем самом и во 
всех его предках, то есть в его суперклассе (В) и суперклассе суперкласса (А). 
public class С extends В { 
public function о ( ) { 
trace("Method o( ) was called"); 
// Использование: 
var clnstance = new C( ); 
// Вызов метода, унаследованного от класса А 
clnstance.m( ); // Выводит: Method m( ) was called 
// Вызов метода, унаследованного от класса В 
clnstance.n( ); // Выводит: Method n( ) was called 
// Вызов метода, определенного в классе С 
clnstance.о( ); // Выводит: Method o( ) was called 
// Обращение к переменной, унаследованной от класса А. 
trace(clnstance.v); // Выводит: 10 
Более того, каждый суперкласс может иметь любое количество подклассов (однако 
у суперкласса нет никакой возможности узнать, какие подклассы расширяют его 
возможности). Следующий код добавляет в наш пример четвертый класс D. Как 
и В, класс D наследуется непосредственно от А. Класс D может использовать методы 
и переменные, определенные в нем самом и в его суперклассе А. 
public class D extends A { 
public function p ( ) { 
trace("Method p( ) was called"): 
Четыре класса из нашего примера образуют так называемое дерево наследования, или 
иерархию классов. Наглядно эта иерархия представлена на рис. 6.1. Обратите  
внимание, что подкласс не может иметь более одного непосредственного суперкласса. 
Все приложения, разработанные с использованием объектно-ориентированного 
подхода, могут быть описаны с помощью диаграммы классов наподобие той, что 
изображена на рис. 6.1. На самом деле многие разработчики перед тем, как приступить 
к написанию кода, создают диаграммы классов. Эти диаграммы могут быть  
неформальными, нарисованными в соответствии с собственной иконографией разработчика, 
или формальными, нарисованными в соответствии со спецификацией изображений 
диаграмм, к которой относится, например, язык UML (Unified Modeling Language) 
(дополнительную информацию можно получить по адресу http://www.uml.org). 
Иерархия классов
Аналогично тому, как мы разрабатываем собственные иерархии классов для наших 
приложений, реализуемых с помощью объектно-ориентированного подхода, язык 
ActionScript тоже организует свои собственные классы в соответствии с иерархией. 
На самом деле любой класс в языке ActionScript (как собственный, так и  
пользовательский) унаследован прямо или косвенно от корневого элемента внутренней 
иерархии языка — класса Object. Класс Object определяет несколько базовых 
методов и переменных, доступных всем классам через наследование. Например, 
любой класс может воспользоваться методом Obj ect. toString ( ),  
возвращающим строковое представление объекта. 
Статические методы и статические переменные не наследуются. В отличие от 
методов и переменных экземпляра, подкласс не наследует статические методы 
и статические переменные своего суперкласса. 
Например, в следующем коде мы определяем статический метод s ( ) в  
классе А. Метод s ( ) не наследуется подклассом В класса А, и, следовательно, к этому 
методу нельзя обратиться в виде В. s ( ). 
public class A { 
public static function s ( ) { 
trace("A.s( ) was called"); 
public class В extends A { 
public function В ( ) { 
B.s( ); // Ошибка! Недопустимая попытка обращения 
// к методу A.s( ) через класс В 
 }
}
145 
Тем не менее в теле любого из классов А или В к статическим методам и  
переменным, определенным в классе А, можно обращаться непосредственно, не указывая 
имя класса, например s ( ) вместо A. s ( ). Но несмотря на это, при обращении 
к статическим методам или статическим переменным вообще разумно указывать 
имя класса. Когда указано имя класса, становится совершенно ясно, к какому  
классу относится метод или переменная. 




BACK NEXT

Сайт является частным собранием материалов и представляет собой любительский информационно-образовательный ресурс. Вся информация получена из открытых источников. Администрация не претендует на авторство использованных материалов. Все права принадлежат их правообладателям