Файл: Основные понятия объектно-ориентированного программирования(ОБЪЕКТНО-ОРИЕНТИРОВАННАЯ ТЕХНОЛОГИЯ).pdf
Добавлен: 29.03.2023
Просмотров: 231
Скачиваний: 2
1.4. Ключевые положения
Ключевые положения объектно-ориентированной технологии были первые сформулированы Аланом Кеем. К ним относятся следующие утверждения:
- в рамках ООП все является объектом;
- все вычисления реализуются при помощи взаимодействия объектов таким образом, что один объект запрашивает выполнение какого-либо действия у другого объекта посредством отправки сообщений. Сообщение содержит запрос на выполнение какого-либо действия, также оно сопровождается списком аргументов, которые требуются для реализации данного действия;
- все объекты обладают собственной независимой памятью, состоящей из других объектов;
- все объекты являются экземплярами классов, отражая общие свойства соответствующих классов;
- классы определяют функциональные возможности объектов. Следовательно, все объекты, принадлежащие одному классу, способны выполнять одни и те же действия;
- классы являются древовидной структурой с общим корнем. Эта структура называется иерархией наследования. Поведение и память отдельных экземпляров являются автоматически доступными любым экземплярам, которые находятся на нижележащих уровнях иерархии [5, 9].
1.5. Выводы
В данной главе рассмотрены основы объектно-ориентированного программирования: описана история возникновения данной технологии, причины ее популярности, а также основные понятия и ключевые положения.
2. OBJECT PASCAL
2.1. Классы
Ранее говорилось, что одним из ключевых понятий объектно-ориентированного подхода является понятие класса. Класс представляет собой структуру, динамически размещаемую в памяти. Все классы строятся на базе абстракций. Для корректной работы абстракции необходимо ограничить доступ к ее внутреннему содержимому. Данное условие реализуется за счет разделения абстракции на две части (см. рисунок 3):
КЛАСС
ИНТЕРФЕЙС
ПОЛЯ
МЕТОДЫ
РЕАЛИЗАЦИЯ
ПОЛЯ
МЕТОДЫ
Рисунок 3 – Две части абстракции
- интерфейс – полная собой совокупность элементов, доступных вне абстракции – основные характеристики состояния и поведения экземпляров;
- реализация – полная совокупность элементов, доступных только в рамках абстракции – внутренняя организация абстракции и механизмы реализации ее поведения.
Наличие интерфейса сокращает возможность разрушения целостности объекта извне. При этом сокрытие особенностей реализации упрощает редактирование реализации класса не только на этапе отладки, но и в процессе модификации всего программного кода. Таким образом, класс определяет существование глобальной области данных в рамках объекта, которая доступна методам этого объекта. Также важно отметить, что доступ к объекту реализуется при помощи специального интерфейса.
Описание класса в языке Object Pascal выглядит следующим образом:
Type <имя> = class (<имя _родительского_класса>)
Private
<строго_скрытые_элементы>
Strict Private
<скрытые_элементы>
Protected
<защищенные_элементы>
Public
<общедоступные_элементы>
Published
<опубликованные_элементы>
end;
В данном описании использованы специальные директивы, отвечающие за разграничение доступа к отдельным элементам класса (см. таблицу 1) [2].
Любой класс содержит как минимум два метода – конструктор и деструктор. Конструктор - метод создания объекта, деструктор – метод его уничтожения. В языке Object Pascal имена конструктора и деструктора произвольны. Конструктор может принимать на вход некоторое количество аргументов. Деструктор не имеет аргументов.
Таблица 1 – Спецификаторы доступа
|
Спецификатор |
Описание |
|
Private |
Класс доступен только в текущем модуле. |
|
Strict Private |
Члены класса, доступные только внутри собственных методов. |
|
Protected |
Члены класса, доступные в производных классах даже в тех случаях, когда они описаны в других модулях. |
|
Public |
Общедоступные члены, на которые не накладываются ограничения. |
|
Published |
Публичные члены класса, доступные в инспекторе объектов. Важно отметить, что массивы не могут являться членами класса. |
Характерное отличие конструктора от других методов – использование ключевого слова «Constructor», которое заменяет классические «procedure» и «function». Метод-деструктор определяется ключевым словом «Destructor».
Перед созданием объекта его необходимо объявить. Объявление экземпляров классов аналогично объявлению переменных. Задача конструктора – выделение памяти под объект. Задача деструктора – освобождение этой памяти после того, как работа с объектом завершена.
Чтобы проверить принадлежность объекта какому-либо классу в языке Object Pascal используется бинарный оператор «is». Первым аргументом этого оператора является имя объекта, вторым имя интересующего класса. В результате выполнения данного оператора возвращается логическое значение. Важно помнить, что если объект объявлен, но не создан, оператор «is» всегда вернет значение «false» [13].
2.2. Свойства
Основное назначение свойств – ограничение доступа к членам класса. Обращение к свойствам реализуется аналогично обычным членам.
Взаимодействие и передача данных между свойствами и данными-членами реализуется с помощью неявного обращения к члену или неявного вызова метода.
Реализация ограничений возможна благодаря спецификаторам доступа. Так, например, спецификатор read предоставляет права на чтение, а спецификатор write – права на запись. В том случае, если спецификаторы явно не указаны, считается, что предоставлены только права на чтение.
Синтаксис объявления свойств:
property <идентификатор>: <тип> <ограничитель>;
Задача ограничителя – разграничение прав доступа. Синтаксис записи ограничителя:
<спецификатор>:<идентификатор>
Ограничители бывают двух видов - простые и сдвоенные. Сдвоенный ограничитель представляет собой запись двух ограничителей, разделенных между собой пробелом.
В большинстве случаев идентификатором свойства является имя того элемента класса, который привязывается к этому свойству. Стоит отметить, что идентификаторами также могут быть имена методов, взаимодействующих с элементами класса, в том случае, если эти элементы и методы уже объявлены в классе.
Частным случаем свойств являются свойства-массивы, с помощью которых реализуется ограниченный доступ к массивам, расположенным внутри объектов. В процессе работы с такими свойствами необходимо указывать индексы интересующих элементов.
Обмен данными между массивами и свойствами реализуется с помощью специального метода, одним из параметров которого является число целого типа.
Синтаксис записи свойств-массивов:
property <свойство>[<параметр>:<тип>] <ограничитель>;
Кроме того, свойства-массивы могут быть помечены в качестве «свойств по умолчанию» (спецификатор «default») Класс может иметь только одно такое свойство. При использовании свойств по умолчанию конструкции объект.свойство[индекс] и объект[индекс] становятся равнозначными.
Еще одним видом свойств являются индексные свойства, связанные с конкретными элементами массива.
Синтаксис записи индексных свойств:
property <свойство> <тип> index <ограничитель>; [12]
2.3. Наследование
Один из основных принципов ООП - наследование. Согласно данному принципу, классы могут строиться на базе других, уже существующих классов, которые называются родительскими. Если у класса один родительский класс, такое наследование называется простым. В противном случае наследование называется множественным.
Одноименные методы в пределах иерархии классов могут переопределяться на нижних уровнях. Для этого необходимо добавить прототип нужного метода в объявление класса-наследника и написать требуемую реализацию.
По умолчанию все методы классов являются статическими. Если обратиться к какому-либо методу объекта базового класса, исполнится метод родительского класса. Если же вызвать тот же метод из наследуемого класса, вызовется соответствующий метод класса-наследника.
Часто при перегрузке методов используются виртуальные методы, основой которых является механизм позднего связывания. В этом случае привязка методов к объектам происходит непосредственно в процессе исполнения программного кода (при вызове конструктора). Важно отметить, что виртуальные методы нельзя перекрыть обычными методами. Чтобы пометить метод виртуальным, используется ключевое слово «dynamic» или «virtual».
Перегрузка виртуального метода реализуется с помощью модификатора «override». В этом случае перегружаемый метод автоматически становится виртуальным.
Наряду с основными методами, также могут наследоваться и конструкторы. Для этого используется оператор «inherited». Также данный оператор используется при наследовании деструктора.
Еще одним вид методов являются абстрактные методы - это динамические или виртуальные методы, реализация которых не определяется в том классе, где они объявлены. Таким образом, заранее предполагается, что эти методы будут переопределяться в классах-наследниках. Абстрактные методы объявляются с ключевым словом «abstract» [15].
2.4. Полиморфизм
При помощи полиморфизма могут задаваться различные реализации некоторого единого по названию метода для классов, расположенных на разных уровнях иерархии. В этом случае одноименные методы называются статическими полиморфными.
В рамках ООП считается, что все реализации одноименных методов представляют собой один полиморфный метод семейства классов. Любая реализация в этом случае является отдельным аспектом полиморфного метода семейства классов. Всякий конкретный аспект статического полиморфного метода определяется объектным типом на этапе компиляции.
Существует также сложный полиморфизм. В этом случае конкретный аспект полиморфного метода также определяется объектным типом, для которого он вызван. Главное отличие состоит в том, что это происходит не на этапе компиляции, а непосредственно в процессе выполнения программы. Данный подход принято называть поздним связыванием.
Необходимость существования и использования позднего связывания объясняется тем, что Object Pascal разрешает указателям на объекты родительского класса присваивать адреса объектов классов потомков.
Так как в случае передачи объектов в качестве параметров применяются указатели, формально описанному параметру типа некоторого класса может соответствовать фактический параметр не только того же типа, но и типа класса, производного от указанного.
В тех случаях, когда реальный тип объекта не определен, связывание объекта и метода на этапе компиляции программы приводит к тому, что при любых условиях (и для объектов родительских классов, и для объектов производных классов) вызывается родительский метод. Применение позднего связывания позволяет правильно определить требуемый аспект полиморфного метода [10].
2.5. Размещение класса и объектов в памяти
Характерной особенностью Object Pascal является тот факт, любой класс после успешной компиляции программы хранит не только основную информацию, но и дополнительную – это данные о типе периода времени выполнения (RTTI – Runtime Type Information). Эта информация хранится в памяти непосредственно перед таблицей виртуальных методов (VMT – Virtual Methods Table). Всякий объект кроме указанных полей также содержит указатель на VMT. Таблица может даже не содержать ссылок, в том случае, если у класса и его предков отсутствуют виртуальные методы. Схема размещения объектов и класса в памяти приведена на рисунке 4.