
- •Предисловие
- •Введение в объектно-ориентированное программирование Основные понятия объектно-ориентированного программирования: инкапсуляция, наследование и полиморфизм Объект
- •Наследование и полиморфизм
- •Агрегация
- •Апология ооп
- •Демонстрация преимущества объектно-ориентированного программирования на примере системы вывода графических изображений
- •Реализация с помощью структурных технологий
- •Реализация с помощью объектно-ориентированных технологий
- •Объектно-ориентированные, объектные и объектно-базированные языки программирования
- •Создание классов и объектов в actionscript 2.0
- •Основы создания классов и объектов
- •Квалификаторы доступа и методы доступа Get/Set Первая версия класса библиографических карточек
- •Вторая версия класса библиографических карточек
- •Задание 1
- •Наследование и полиморфизм в actionscript 2.0 Наследование
- •Полиморфизм
- •Задание 2
- •Литература
Вторая версия класса библиографических карточек
Созданный нами класс великолепно работает, и более того, он уже стал достаточно похож на классы реальных приложений информационных систем. Но все ли здесь правильно реализовано с точки зрения идеологии объектно-ориентированного программирования? Стоит вспомнить, что объект должен скрывать свою реализацию, а у нас имеется возможность непосредственно обращаться к атрибутам объекта (автор, название и т. д.), которые должны оставаться исключительно в его ведении. А это может стать источником проблем. В самом деле, возьмем, к примеру, автомобиль. У него имеется двигатель, который является его атрибутом. Было бы не очень хорошо, если бы водителю часто приходилась открывать капот. Еще хуже, если бы ему пришлось менять скорость, непосредственно обращаясь к двигателю. В идеале водитель вообще не должен помнить о двигателе. У водителя есть педаль акселератора и именно с помощью нее он меняет скорость.
Модифицируем наш класс библиографических карточек согласно требованиям объектно-ориентированного программирования и сокроем реализацию. Для этого в ActionScript 2.0 имеются два квалификатора доступа: public и private. Первый делает члены класса - атрибуты и методы -доступными (открытыми) для любых объектов, в то время как второй позволяет обращаться к ним лишь объектам того, в которых они объявлены, т. е. делает их закрытыми для «чужих» объектов. В ActionScript 2.0 по умолчанию атрибуты являются открытыми. Для того чтобы сделать атрибут закрытым, следует перед ним установить квалификатор private.
'Сделаем атрибуты нашего класса закрытыми:
//Автор
private var m_sAuthor:String;
//Заглавие
private var m_sTitle:String;
//Издательство
private var m_sPublisher:String;
//Год издания
private var m_nYear:Number;
//Число страниц
private var m_nPageCount:Number;
Теперь к ним уже нельзя будет обратиться из других объектов. Они попадают в безраздельное владение CbibliographicCard.
Следует заметить, что закрытыми могут быть не только атрибуты, но и методы, которые используются исключительно в пределах одного класса. Обычно это вспомогательные методы, предоставляющие какую-то функциональность, необходимую только этому классу. Так, в нашем классе мы могли бы ввести атрибут, в котором бы содержалось библиографическое описание в виде строки. Тогда можно было создать метод, формирующий эту строку. И если предположить, что содержимое библиографической карточки не изменяется или обеспечить при каждом таком изменении вызов этого метода (о том, как это сделать речь пойдет дальше), то целесообразно данный метод сделать закрытым, разместив перед ним квалификатор доступа private.
Но что если нам вдруг понадобится изменить значения атрибутов? Например, потребуется отредактировать нашу карточку. Теперь атрибуты являются закрытыми и непосредственный доступ к ним невозможен. Для решения этой проблемы служат методы доступа: устанавливающие значение атрибута (метод Set) и считывающие его значение (метод Get).
Добавим методы доступа в наш класс.
//------------Методы доступа------------------
//----------------Set-------------------------
function SetAuthor(sAuthor:String):Void
{m_sAuthor = sAuthor;}
function SetTitle(sTitle:String):Void
{m_sTitle = sTitle;}
function SetPublisher(sPublisher:String):Void
{m_sPublisher = sPublisher;}
function SetYear(nYear:Number):Void
{m__nYear = nYear;}
function SetPageCount(nPageCount:Number):Void
{m_nPageCount = nPageCount;}
//----------------Get-------------------------
function GetAuthor():String{return m_sAuthor;}
function GetTitle():String{return m_sTitle;}
function GetPublisher():String{return m_sPublisher;}
function GetYearO:Number{return m_nYear;}
function GetPageCount () :Number {return m_nPageCount;}
//////////////////////////////////////////////
Приведем полный текст кода, описывающего класс.
class CBibliographicCard
{
//Автор
private var m_sAuthor:String;
//Заглавие
private var m_sTitle:String;
//Издательство
private var m_sPublisher:String;
//Год издания
private var m_nYear:Number;
//Число страници
private var m_nPageCount:Number;
//------------Методы доступа------------------
//----------------set-------------------------
function SetAuthor(sAuthor:String):Void
{m_sAuthor = sAuthor;}
function SetTitle(sTitle:String):Void
{m_sTitle = sTitle;}
function SetPublisher(sPublisher:String):Void
{m_sPublisher = sPublisher;}
function SetYear(nYear:Number):Void
{m_nYear = nYear;}
function SetPageCount(nPageCount:Number):Void
{m_nPageCount = nPageCount;}
//----------------Get--------------------------
function GetAuthor():String{return m_sAuthor;}
function GetTitleO:String!return m_sTitle;}
function GetPublisher0:String{return m_sPublisher;}
function GetYear():Number{return m nYear;}
function GetPageCount():Number{return m_nPageCount;}
//////////////////////////////////////////////
//Конструктор
function CBibliographicCard(sAuthor:String, sTi-tle:String,
sPublisher:String, nYear:Number, nPageCount:Number)
{
//Производим инициализацию атрибутов
m_sAuthor = sAuthor;]
m_sTitle = sTitle;
m_sPublisher = sPublisher;
m_nYear = nYear;
m_nPageCount = nPageCount;
}
function GetDescription():String
{
//Формируем описание монографии в виде одной строки
//и возвращаем эту стоку с помощью оператора return
return m_sAuthor + " " + m_sTitle + "."
+ m_sPublisher + ", " + String(m_nYear)
+ ". " + String(m_nPageCount) + " стр.";
}
}
Использование методов доступа является обычной практикой при использовании методологии объектно-ориентированного программирования. Но есть ли, в самом деле, разница, как мы будем считывать и устанавливать значения атрибутов? На первый взгляд может показаться, что нет, и создание методов доступа просто усложняет жизнь программиста и утяжеляет текст исходного кода. Но это не так. Во-первых, варьирование возможностью доступа позволяет управлять правами доступа к содержимому объекта. Аналогичным образом дело обстоит и в реальном мире. Трудно представить себе организацию, в которой был бы открыт доступ всем желающим в любые ее помещения. Ни к чему хорошему это бы не привело. Как ни к чему хорошему не привело бы отсутствие разграничения прав доступа к несметному числу составляющих сложной программной системы.
Во-вторых, может возникнуть ситуация, что каждый раз при установлении атрибуту нового значения потребуется выполнять какие-то действия. Мы уже упоминали об этом в связи с возможностью существования закрытых методов. Так, если бы мы отказались формировать строку библиографического описания в методе GetDescription(), низведя его до простого метода доступа, нам пришлось бы найти способ обеспечить актуальность содержимого этого атрибута в любой момент времени. В самом деле, в случае изменения значения какого-либо частного атрибута, необходимо вновь сформировать строку библиографического описания. А сделать это можно лишь, вызывая из методов доступа, устанавливающих значения отдельных атрибутов (автор, название и т. д.), метод, формирующий строку библиографического описания.