Перекрытие методов экземпляра  ActionScript 

 

 

В этой главе мы уже познакомились с такими методиками наследования, как  

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

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

Сейчас мы рассмотрим еще одну методику — переопределение, при которой подкласс 

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

Переопределение позволяет приспособить существующий класс для решения  
специфической задачи путем дополнения, наложения ограничений или даже  
аннулирования одной или нескольких исходных возможностей. Переопределение метода 
на техническом языке называется перекрытием. 
Чтобы перекрыть метод экземпляра суперкласса, мы должны добавить в подкласс 
описание метода экземпляра с таким же именем, предварив его ключевым  
словом override. Например, рассмотрим следующий код, в котором создается класс 
А с методом экземпляра m ( ): 
public class A { 
// Объявление метода экземпляра в суперклассе 
public function m ( ) { 
traceC\'A\'s m( ) was called"); 
Рассмотрим также следующий код, в котором создается класс В, унаследованный 
от класса А: 
// Класс В является подклассом класса А 
public class В extends A { 
Чтобы перекрыть метод m ( ) в классе В, мы используем следующий код: 
public class В extends A { 
// Перекрытие метода суперкласса т( ) 
Глава 6. Наследование 
override public function m ( ) { 
traceC\'B\'s m( ) was called"): 
Обратите внимание, что версия метода m ( ) класса В обладает не только таким же 
именем, как у версии метода класса А, но и таким же модификатором управления 
доступом (то есть public). 
Когда метод m ( ) вызывается через экземпляр класса А, среда выполнения Flash 
использует описание метода из класса А. Однако когда метод m ( ) вызывается  
через экземпляр класса В, среда Flash использует описание метода из класса В вместо 
описания из класса А: 
var alnstance = new A( ); 
alnstance.m( ); // Выводит: A\'s m( ) was called 
var blnstance = new B( ); 
blnstance.m( ); // Выводит: B\'s m( ) was called 
Рассмотрим более реальный пример. Предположим, что мы разрабатываем  
геометрическую программу, отображающую прямоугольники и квадраты.  
Прямоугольники в нашей программе будет представлять класс Rectangle,  
продемонстрированный в следующем коде: 
public class Rectangle { 
protected var w = 0: 
protected var h = 0: 
public function setSize (newW. newH) { 
w = newW; 
h = newH; 
public function getArea ( ) { 
return w * h: 
Для представления квадратов в программе мы могли бы создать совершенно  
независимый класс Square. Однако квадрат на самом деле представляет собой не 
что иное, как прямоугольник с равными сторонами. Чтобы воспользоваться этим 
подобием, мы создадим класс Square, расширяющий класс Rectangle, но при 
этом модифицирующий метод set Size ( ) для предотвращения присваивания 
значений переменным w и h в тех случаях, когда значения параметров newW и newH 
не равны между собой. Это ограничение относится только к квадратам, а не к  
прямоугольникам вообще, поэтому оно не реализуется в классе Rectangle. 
Рассмотрим код класса Square, в котором продемонстрирован перекрытый метод 
setSize ( ): 
public class Square extends Rectangle { 
override public function setSize (newW. newH) { 
// Это ограничение, накладываемое классом Square 
if (newW == newH) { 
w = newW; 
h = newH; 
При вызове метода setSize ( ) через экземпляр класса Square или Rectangle  
среда выполнения Flash использует ту версию метода, которая соответствует  
фактическому классу экземпляра. Например, в следующем коде мы вызываем метод s e t S i z e ( ) 
через экземпляр класса Rectangle. Среда Flash знает, что классом экземпляра  
является Rectangle, поэтому вызывается версия метода setSize ( ) из этого класса: 
var r = new Rectangle( ); 
r.setSizeD.5); 
trace(r.getArea( )); // Выводит: 20 
В отличие от этого, в следующем коде мы вызываем метод setSize ( ) через 
экземпляр класса Square. На этот раз среда выполнения Flash знает, что классом 
экземпляра является Square, поэтому версия метода setSize ( ) вызывается 
именно из этого класса, а не из класса Rectangle: 
var s = new Square( ); 
s.setSizeD.5): 
trace (s.getArea( )): // Выводит: О (Метод setSize( ) предотвращает 
// присваивание недопустимых значений) 
В предыдущем коде результат вызова метода s . getArea ( ) равен 0. Это говорит 
о том, что значения переменных w и h не были установлены при вызове метода 
s . setSize ( ). В версии метода setSize ( ) класса Square значения  
переменным w и h присваиваются только в том случае, когда значения параметров newW 
и newH равны между собой. 
Вызов перекрытого метода экземпляра. Когда подкласс перекрывает метод  
экземпляра, версия этого метода, определенная в суперклассе, не теряется. Экземпляры 
подкласса могут обращаться к этой версии метода посредством оператора super, 
позволяющего вызывать перекрытый метод следующим образом: 
super.имяМетода (аргумент1, аргумент2... аргумент): 
В этом коде имяМетода обозначает имя вызываемого перекрытого метода, а аргумент1, 
аргумент2. . . аргумент — список аргументов, передаваемых в этот метод (другие  
варианты использования оператора super будут рассмотрены далее в этой главе). 
В качестве примера вызова перекрытого метода вернемся к сценарию с классами 
Square и Rectangle. В предыдущем разделе наш метод Square. setSize ( ) 
без необходимости дублировал код метода Rectangle. setSize ( ). Рассмотрим 
версию метода, определенную в классе Rectangle: 
Глава 6. Наследование 
public function setSize (newW, newH) { 
w = newW; 
h = newH; 
В версии метода setSize ( ), определенной в классе Square, просто добавлен 
оператор if: 
override public function setSize (newW. newH) { 
if (newW == newH) { 
w = newW; 
h = newH; 
Чтобы избежать дублирования кода, используемого в обоих методах для  
присваивания значений переменным w и h, мы можем воспользоваться оператором 
super, как показано в следующей модифицированной версии метода Square. 
setSize ( ): 
override public function setSize (newW. newH) { 
if (newW == newH) { 
// Вызов метода setSize( ) суперкласса над текущим экземпляром 
super.setSize(newW, newH); 
Модифицированный метод setSize ( ) класса Square проверяет, одинаковы ли 
значения параметров newW и newH. Если значения одинаковы, то вызывается метод 
setSize ( ) класса Rectangle над текущим экземпляром. Метод setSize ( ) 
класса Rectangle позаботится о присваивании значений переменным w и п. 
Приведенный пример с методом setSize ( ) демонстрирует, как подкласс может 
перекрывать метод для ограничения его поведения. Кроме того, подкласс может 
перекрывать метод для дополнения его поведения. Например, следующий код  
создает класс ScreenRectangle, являющийся подклассом класса Rectangle и  
отображающий на экране прямоугольник. Подкласс ScreenRectangle перекрывает 
метод s e t S i z e ( ), сохраняя поведение перекрываемого метода, но при этом  
добавляя вызов метода draw ( ), в результате чего размеры прямоугольника на экране 
изменяются всякий раз при вызове метода s e t S i z e ( ): 
public class ScreenRectangle extends Rectangle { 
override public function setSize (newW, newH) { 
// Вызов версии метода setSize( ) класса Rectangle 
super.setSize(newW, newH); 
// Теперь отображаем прямоугольник на экране 
draw( ); 
public function draw ( ) { 
// Здесь размещается код, отображающий прямоугольник на экране 
Перекрытие можно использовать и для аннулирования поведения метода.  
Методика очень проста: версия перекрытого метода подкласса не выполняет никаких  
действий. Например, следующий код демонстрирует подкласс ReadOnlyRectangle, 
блокирующий метод setSize ( ) класса Rectangle, в результате чего  
исключается возможность изменения размера для экземпляра этого подкласса: 
public class ReadOnlyRectangle extends Rectangle { 
// Следующее определение фактически блокирует метод setSize( ) 
// для экземляров класса ReadOnlyRectangle. 
override public function setSize (newW, newH) { 
// Никаких действий 




BACK NEXT

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