Объектно-ориентированное программирование. 2
Оглавление
- Введение
- Объекты
- Свойства
- Объекты: наследующие записи
- Объекты и модули
- Методы
- Определения методов
- Программирование в "действительном залоге"
- Источники информации
Введение
Объектно-ориентированное программирование представляет собой метод программирования, который весьма близко напоминает наше поведение. Оно является естественной эволюцией более ранних нововведений в разработке языков программирования. Объектно-ориентированное программирование является более структурным, чем все предыдущие разработки, касающиеся структурного программирования. Оно также является более модульным и более абстрактным, чем предыдущие попытки абстрагирования данных и переноса деталей программирования на внутренний уровень.
Мы
живем в мире объектов. Стол, автомобиль,
ручка, классная доска – все это
объекты. Наряду с физическими существуют
так же абстрактные объекты, типичными
представителями которых
Объекты характеризуются атрибутами. Так атрибутами автомобиля являются максимальная скорость, мощность двигателя, цвет кузова и т. д. Атрибутами усилителя являются частотный диапазон, выходная мощность, коэффициент нелинейных искажений, уровень шума и т. д.
Помимо
атрибутов объекты обладают некоторыми
функциональными возможностями, которые
в объектно-ориентированном
Таким
образом, объект инкапсулирует атрибуты
и методы, скрывая от других объектов
взаимодействующих с ним и
использующих его функциональность,
свою реализацию. Так для того чтобы
переключить телевизионную
Объект – это экземпляр некоторого класса объектов или просто класса. Так автомобиль Audi 6 является экземпляром класса автомобилей данной модели, приемник Sony SW-7600G так же будет представителем класса одноименных приемников. Таким образом, класс – это абстрактное понятие. Отношение класса и объекта примерно такое же, как платоновские идеи и объекты реального мира. На UML – унифицированном языке моделирования – класс отображается в виде прямоугольника, разделенного на три части. В первой содержится имя класса, во второй – атрибуты, в третьей – методы
Изображения
класса и отношений генерализации
в UML: а – изображение класса; б
– одиночное наследование; с –
множественное наследование
Свойства
Объектно-ориентированный язык программирования характеризуется тремя основными свойствами:
1.Инкапсуляция. Комбинирование записей с процедурами и функциями, манипулирующими полями этих записей, формирует новый тип данных - объект.
Некоторые
объектно-ориентированные
Объекты TEmployee и THourly написаны таким образом, что совершенно исключена необходимость прямого обращения к их внутренним полям данных:
type
TEmployee = object
Name, Title: string[25];
Rate: Real;
procedure Init (AName, ATitle: string; ARate: Real);
function GetName : String;
function GetTitle : String;
function GetRate : Real;
function GetPayAmount : Real;
end;
THourly = object(TEmployee)
Time: Integer;
procedure Init(AName, ATitle: string; ARate:
function GetPayAmount : Real;
end;
Здесь
присутствуют только четыpе поля данных:
Name, Title, Rate и Time. Методы ShowName и ShowTitle выводят
фамилию pаботающего и его должность, соответственно.
Метод GetPayAmount использует Rate, а в случае
pаботающего THourly и Time для вычисления суммы
выплат pаботающему. Здесь уже нет необходимости
обpащаться непосpедственно к этим полям
данных.
Предположив существование экземпляра AnHourly типа THourly, можно использовать набор методов для манипулирования полями данных AnHourly, например:
with AnHourly do
begin
Init ("Allison Karlon, Fork lift operator" 12.95, 62);
{ Выводит на экpан фамилию, должность и сумму выплат}
Show;
end;
2.Наследование. Определение объекта и его дальнейшее использование для построения иерархии порожденных объектов с возможностью для каждого порожденного объекта, относящегося к иерархии, доступа к коду и данным всех порождающих объектов.
Наследование является отношением класс – подкласс.
При наследовании все атрибуты и методы родительского класса наследуются классом-потомком. Наследование может быть многоуровневым, и тогда классы, находящиеся на нижних уровнях иерархии, унаследуют все свойства (атрибуты и методы) всех классов, прямыми или косвенными потомками которых они являются. Класс B унаследует атрибуты и методы класса A и, следовательно, будет обладать атрибутами A, B, C и D и методами A, B, C и D, а класс C – атрибутами A, B, C, E, F и методами A, B и E.
Помимо единичного, существует и множественное наследование, когда класс наследует сразу нескольким классам (рис. 1, с). При этом он унаследует свойства всех классов, потомком которых он является. При использовании множественного наследования необходимо быть особенно внимательным, так как возможны коллизии, когда класс-потомок может унаследовать одноименные свойства, с различным содержанием.
Такая проблема известна как «Алмаз Никсона». Ее суть состоит в том, как должен повести себя Никсон, который является квакером и в то же время принадлежит к республиканской партии. А известно, что квакеры – пацифисты, в то время как республиканцы – сторонники военного решения проблем. На лицо явная коллизия. В разных языках, поддерживающих парадигму ООП и допускающих множественное наследование (а оно допустимо не во всех языках и, например, язык Java, широко распространенный в сфере интернет-приложений, не поддерживает множественного наследования), она преодолевается по-разному, но в любом случае необходимо быть предельно осторожным при возникновении таких ситуаций.
При
наследовании одни методы класса могут
замещаться другими. Так, класс транспортных
средств будет обладать обобщенным
методом движения. В классах-потомках
этот метод будет конкретизирован:
автомобиль будет ездить, самолет
– летать, корабль – плавать.
Такое изменение семантики
3.Полиморфизм.
Присваивание действию одного имени, которое
затем совместно используется вниз и вверх
по иерархии объектов, причем каждый объект
иерархии выполняет это действие способом,
именно ему подходящим.
Объекты: наследующие записи
В терминах Паскаля, объект во многом схож с записью, которая является оболочкой для объединения нескольких связанных элементов под одним именем. Предположим, нужно разработать программу вывода платежной ведомости, печатающую отчет и показывающую, сколько нужно выплатить каждому служащему за рабочий день. Запись можно организовать следующим образом:
TEmployee = record
Name: string[25];
Title: string[25];
Rate: Real;
end;
По соглашению все типы начинаются с буквы T
Здесь TEmployee является типом записи, т.е. шаблоном, используемым компилятором для создания переменных типа запись. Переменная типа TEmployee является экземпляром этого типа. Термин "экземпляр" нередко встречатся в Паскале. Он постоянно применяется теми, кто использует методы объектно-ориентированного программирования.
Можно оперировать с типом TEmployee двояко. Можно рассматривать поля Name, Title и Rate по отдельности, а когда о полях, как о работающих одновременно для описания конкретного рабочего, можно рассматривать их совокупность, как TEmployee.
Предположим, что фирме работает несколько типов рабочих. Одни из них имеют почасовую оплату, другие - оклад, третьи - тарифную ставку и так далее. Программа должна учитывать все эти типы. Можно создать другой тип записи для каждого типа рабочего. Например, для получения данных о том, сколько должен получить рабочий с почасовой оплатой, нужно знать, сколько часов он отработал. Можно построить запись THourly вида:
THourly = record
Name: string[25];
Title: string[25];
Rate: Real;
end;
Такая конструкция работает, и программисты, работающие на Паскале, делают это постоянно. Единственное, чего этот метод не делает, так это то, что он заставляет вас думать о том, с чем вы работаете в вашем программном
обеспечении. Вам следует задаться вопросом типа; "Чем почасовик отличается от дpугих pабочих?" Ответ прост: почасовик - это pабочий, котоpому платится за количество часов pаботы. Продумайте снова первую часть предложения; почасовик - это pабочий...
Запись для pаботника-почасовика hourly должна иметь все записи, котоpые имеются в записи employee. Tип THourly является дочерним типом для типа TEmployee. THourly наследует все, что принадлежит TEmployee, и кроме того имеет кое-что новое, что делает THourly уникальным.
Этот процесс, с помощью которого один тип наследует характеристики другого типа, называется наследованием. Наследник называется порожденным (дочерним) типом, а тип, которому наследует дочерний тип, называется порождающим (родительским) типом.
Ранее известные типы записей Паскаля не могут наследовать. Однако Borland Pascal расширяет язык Паскаль для поддержки наследования. Одним из этих расширений является новая категория структуры данных, связанная с записями, но значительно более мощная. Типы данных в этой новой категории определяются с помощью нового зарезервированного слова object. Тип объекта может быть определен как полный, самостоятельный тип в манере описания записей Паскаля, но он может определяться и как потомок существующего типа объекта путем помещения, порождающего (родительского) типа в скобки после зарезервированного слова object.
В
приводимом здесь примере платежной
ведомости два связанных типа
объектов могли бы определяться следующим
образом:
type
TEmployee = object
Name: string[25];
Title: string[25];
Rate : Real;
end;
THourly = object(TEmployee)
Time : Integer;
end;
здесь использование скобок означает наследование.
Здесь TEmployee является родительским типом, а THourly - дочерним типом. Этот процесс может продолжаться неопределенно долго. Можно определить дочерний тип THourly, дочерний к типу THourly тип и т.д. Большая часть конструирования объектно-ориентированных прикладных программ состоит в построении такой иерархии объектов, являющейся отражением генеалогического дерева объектов в приложениях.
Все возможные типы, наследующие тип TEmployee, называются дочерними типами типа TEmployee, тогда как THourly является непосредственным дочерним типом типа TEmployee. Наоборот, TEmployee является непосредственным родителем типа THourly. Тип объекта (в точности как подкаталог в DOS) может иметь любое число непосредственных дочерних типов, но в то же время только одного непосредственного родителя.
Как показали данные определения, объекты тесно связаны с записями. Новое зарезервированное слово object является наиболее очевидным различием, но как вы увидите позднее, имеется большое число других различий, некоторые из которых довольно тонкие.
Например, поля Name, Title и Rate в типе TEmployee не указаны явно в типе THourly, но в любом случае тип THourly содержит их благодаря свойству наследования. Можно говорить о величине Name типа THourly в точности так же, как о величине Name типа TEmployee.
Экземпляры объектных типов
Экземпляры объектных типов описываются в точности так же, как в Паскале описывается любая переменная, либо статическая, либо указатель, ссылающийся на размещенную в динамической памяти переменную:
type
PHourly = ^THourly;
var
StatHourly: THourly; { готово }
DynaHourly: PHourly; { перед использованием память должна
выделяться с помощью New }
Поля объектов
Можно обратиться к полю объекта в точности так же, как к полю обычной записи, либо с помощью оператора with, либо путем уточнения имени с помощью точки. Например:
AnHourly.Rate := 9.45;
with AnHourly do
begin
Name := "Sanderson, Arthur";
Title := "Word processor";
end;
Наследуемые поля объектов не интерпретируются особым образом только потому, что они являются наследуемыми.
Наследуемые
поля являются столь же доступными, как
если бы они были объявлены внутри типа
объекта. Например, даже если Name, Title и Rate
не являются частью описания типа THourly
(они наследованы от типа TEmployee), то можно
ссылаться на них, словно они описаны в
THourly.
Объекты и модули
Имеет
смысл определять объекты в модуле
посредством описаний типа объекта
в интерфейсной части модуля, а
тела процедур и методы объекта - в
секции реализации. Для определения
объекта в модуле не требуется
никаких специальных
Примечание: Экспортируемый - означает "определенный в интерфейсной части модуля".
Модули могут иметь свои собственные приватные (частные) определения типов объектов внутри выполняемой секции, и эти типы подвержены тем же ограничениям, как и всякие другие типы, определенные в секции реализации. Типы объектов, определенные в интерфейсной части модуля, могут иметь дочерние типы объектов, определенные в секции реализации модуля. В том случае, когда модуль B использует модуль A, модуль B также может определять дочерние типы любого типа объекта, экспортируемого модулем A.
Описанные
ранее типы объектов и методы можно
определить в модуле, как показано
в программе WORKERS.PAS на дистрибутивном
диске. Чтобы использовать типы объектов
и методы, определенные в модуле
Workers, вы можете просто использовать этот
модуль в своей программе и описать экземпляр
типа THourly в секции переменных программы:
program HourPrt;
uses WinCrt, Workers;
var
AnHourly: THourly;
.
.
.
Для
создания и вывода фамилии pабочего-почасовика,
его должности и pазмеpа выплаты, пpедставленной
пеpеменной AnHourly, вы просто вызываете методы
AnHourly, используя следующий синтаксис:
AnHourlye.Init("Sara Adams", "Account manager", 1400);
{ записывает в экземпляp THourly }
{ данные для Саpы Адамс: фамилию, }
{ должность и pазмеp выплаты. }
AnHourly.Show;
Примечание: Объектами могут быть также типизированные константы.
Объекты,
будучи очень схожими с записями,
могут использоваться внутри оператора
with. В этом случае указание имени объекта,
являющегося собственником методов, не
является необходимым:
with AnHourly do
begin
Init("Sara Adams", "Account manager", 1400);
Show;
end;
Как
и в случаях с записями, объекты
могут передаваться в качестве параметра
процедуре и могут размещаться
в динамически распределяемой памяти.
Секция private
В некоторых случаях может иметься части описаний объектов, которые экспортировать нежелательно. Например, можно предусмотреть объекты для других программистов, которые они могут использовать, но не могут непосредственно манипулировать с данными объекта. Чтобы облегчить это, Borland Pascal позволяет задавать внутри объектов приватные (закрытые) поля и методы.
Приватные поля и методы доступны только внутри того модуля, в котором описан объект. В предыдущем примере, если бы тип THourly содержал приватные поля, то доступ к ним можно было бы получить только в модуле THourly. Даже если другие части объекта THourly можно было бы экспортировать, (части, описанные, как приватные, были бы недоступными.
Приватные
поля и методы описываются непосредственно
после обычных полей и методов,
вслед за зарезервированным словом
private. Таким образом, полный синтаксис
описания объекта будет следующим:
type
NewObject = object(родитель)
поля; { общедоступные }
методы; { общедоступные }
private
поля; { приватные }
методы; { приватные }
end;
Методы
Методы являются одними из наиболее примечательных атрибутов объектно-
ориентированное программирования. Рассмотрим задачу инициализации записи со следующим определением:
TEmployee = object
Name: string[25];
Title: string[25];
Rate: Real;
end;
Большинство
программистов использовали бы оператор
with для присвоения полям Name, Title и Rate начальных
значений:
var
MyEmployee: Employee;
with MyEmployee do
begin
Name := "Sanderson, Arthur";
Title := "Word processor";
Rate := 9.45;
end;
Это
тоже неплохо, но здесь ограничены одной
специфическим экземпляром
procedure InitTEmployee(var Worker: TEmployee; AName,
ATitle: String; ARate: Real);
begin
with Worker do
begin
Name := NewName ;
Title := NewTitle;
Rate := NewRate;
end;
end;
Метод
- это процедура или функция, объединенная
с данным типом столь тесно, что
метод является как бы окруженным
невидимым оператором with, что делает
экземпляр данного типа доступными изнутри
для метода. Определение типа включает
заголовок метода. Полное определение
метода квалифицируется в имени типа.
Тип объекта и метод объекта являются
двумя лицами этой новой разновидности
структуры, именуемой методом.
type
TEmployee = object
Name, Title: string[25];
Rate: Real;
procedure Init (NewName, NewTitle: string[25];
NewRate: Real);
end;
procedure TEmployee.Init (NewName, NewTitle: string[25];
NewRate: Real);
begin
Name := NewName ; { Поле Name объекта TEmployee }
Title := NewTitle; { Поле Tutle объекта TEmployee }
Rate := NewRate; { Поле Rate объекта TEmployee }
end;
Для инициализации экземпляра типа TEmployee нужно вызвать его метод, словно метод является полем записи, что имеет вполне реальный смысл:
var
AnEmployee: TEmployee;
AnEmployee.Init("Sara Adams, Account manager, 15000");
{пpосто, не так ли?}
Программирование в "действительном залоге"
Большая часть из того, что говорилось об объектах до сих пор, исходит из удобств и перспектив Borland Pascal. Объектно-ориентированное программирование имеет свое собственное отдельное множество понятий, частично благодаря началам объектно-ориентированного программирования в научных кругах, однако также и потому, что эта концепция действительно является радикально отличной от других.
Примечание:
Объектно-ориентированные
Было бы полезно представить функцию AnHourly.GetPayAmount как, например, дающую распоряжение объекту AnHourly "Вычислить размер вашей ежедневной платы". Центральной концепцией здесь является объект. Этот объект обслуживают как список методов, так и список полей данных, содержащихся в объекте. И ни код, ни данные не являются здесь "директором".

- Объектно-ориентированное программирование
- Объектно-ориентированные базы данных
- Объектно-ориентированные базы данных
- Объектно-ориентированные технологии программирования прикладных программных средств. Определение классов
- Объектно ориентированный модель данных
- Объектно-ориентированный подход в имитационном моделировании
- Объектно-ориентированный подход к программированию
- Объект и субъект управления
- Объект конфликта
- Объект криминалистики
- Объект налога, как основание возникновения налоговой обязанности
- Объект налогообложения
- Объект налогообложения - доходы
- Объектно-ориентированное программирование