Доступ к полям и методам, описанным в классе-родителе, осуществляется так же, как к собственным.

Типизация. Напомним, тип — это точная характеристика свойств, включая структуру и поведение, относящуюся к неко­торой совокупности объектов. Типизация — это ограничение, которое накладывается на класс объектов и препятствует взаи­мозаменяемости различных классов или сильно сужает воз­можность такой замены.

Использование принципа типизации обеспечивает:

раннее обнаружение ошибок, связанных с недопустимыми операциями над программными объектами (ошибки обна­руживаются на этапе компиляции программы при провер­ке допустимости выполнения данной операции над про­граммным объектом);

упрощение документирования;

возможность генерации более эффективного кода.

ООП возможна статическая и динамическая связь имени объекта и его типа. В первом случае это означает определение типов переменных во время компиляции. Во втором — тип вы­ражения определяется во время исполнения приложения. Из принципов динамической связи и наследования вытекает очень важное свойство, присущее объектам — полиморфизм. Поли­морфизм — это выделение некоторого действия, т. е. действие должно иметь имя, и создание средств использования действия объектами иерархии, причем каждый класс реализует это дей­ствие так, как оно для него подходит.

Итак, при создании иерархии классов может обнаружиться, что некоторые свойства объектов, сохраняя название, изменя­ются по сути.

НЕ нашли? Не то? Что вы ищете?

Для реализации таких иерархий должен быть предусмотрен полиморфизм, обеспечивающий возможность задания различ­ных реализаций некоторого единого по названию метода для классов различных уровней иерархии. В ООП такой полимор­физм называется простым, а методы, имеющие одинаковое на­звание, — статическими полиморфными. В ранее рассмотрен­ных упражнениях статическим полиморфным методом является, например, конструктор Create.

Совокупность полиморфных методов с одним именем для иерархии классов образует единый полиморфный метод иерар­хии, в котором реализация полиморфного метода для конкрет­ного класса представляет отдельный аспект.

Сложный полиморфизм. Полиморфными объектами, или по­лиморфными переменными, называются переменные, которым в процессе выполнения программы может быть присвоено зна­чение, тип которого отличается от типа переменной.

В языках со строгой типизацией такая ситуация может воз­никнуть

при передаче объекта типа класса-потомка в качестве фак­тического параметра подпрограмме, в которой этот пара­метр описан как параметр типа класса-родителя (явно — в списке параметров или неявно — в качестве внутреннего параметра, используемого при вызове методов — Self);

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

Тип полиморфного объекта становится известным только на этапе выполнения программы, соответственно, при вызове поли­морфного метода для такого объекта нужный аспект также дол­жен выполняться на этапе выполнения. Для этого в языке должен быть реализован механизм позднего связывания, позволяющий определять тип объекта и аспект полиморфного метода, к которо­му идет обращение в программе, на этапе ее выполнения.

С помощью механизма позднего связывания реализуется опе­ративная перестройка программы в соответствии с типами ис­пользуемых объектов.

Рассмотрим это свойство на практике.

Упражнение. Разработайте класс Окружность. Решение

Определим новый класс TCircle (окружность). Окружность определяется центром с координатами х, у и радиусом г. Объ­екты этого типа можно сделать видимыми или невидимыми, задать цвет изображения, переместить и т. д. В связи с этим можно определить новый класс как потомок класса TPoint:

TCircle = class (TPoint)

Private
Fr: Integer; {радиус}

Public

Constructor Create(InitX, InitY, InitR: Integer); Destructor Destroy;

Function GetR: Integer; {возвращает значение радиуса}

Procedure Show; {спрятать}

Procedure Hide; {отобразить}

Procedure Move (NewX, NewY: Integer); {переместить}

End;

Классы TPoint и TCircle связаны отношением наследования и содержат методы Hide (спрятать), Show (отобразить) и Move (переместить). Очевидно, что методы Show и Hide для каждого класса свои, но логика метода Move совпадает:

Переместить:

Спрятать объект; {вызов метода Hide}

Изменить координаты объекта; {x:=NewX; y:=NewY}

Отобразить объект; {вызов метода Show}

Поэтому естественным было бы желание определить метод Move только в TPoint так, чтобы класс-потомок TCircle унасле­довал его без определения. Но в методе Move ссылки на методы Hide и Show формируются на стадии компиляции. Это жест­кая, статическая связь, и без ее «разрыва», т. е. реализации ме­ханизма более позднего формирования ссылок на методы не на стадии компиляции, а на стадии выполнения (динамическое связывание), реализовать это невозможно. Добавление к заго­ловку метода зарезервированного слова virtual объявляет его виртуальным, т. е. связь с этим методом устанавливает на ста­дии выполнения программы. Перепишем описание классов сле­дующим образом:

TPoint = class (TPosition)

Procedure Show; virtual; Procedure Hide; virtual;

end;

TCircle = class (TPoint)

Procedure Show; override; Procedure Hide; override;

end;

Директива override используется для переопределения фун­кциональности метода-предка, она необходима для поддержки полиморфной иерархии.

Реализация динамической связи для объектов, имеющих хотя бы один виртуальный метод, осуществляется с помощью таблицы виртуальных методов (ТВМ). Она содержит адреса виртуальных методов. Для каждого класса во время компиля­ции программы строится одна ТВМ (рис. 1.3.2).

Формирование связи между экземпляром класса (объектом) и ТВМ осуществляет конструктор.

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

Итак, мы смогли исключить метод Move из описания класса TCircle, сделав его полиморфным. Все объекты классов TPoint и TCircle будут использовать его, причем так, как им это необ­ходимо.

Сформулируем правила, которые важно выполнять при ра­боте с виртуальными методами:

если в некотором классе метод описан как виртуальный, то все производные классы, включающие метод с тем же именем, должны описать этот метод как полиморфный (override). Нельзя заменить виртуальный метод статиче­ским;

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

В дополнении к виртуальным методам, для реализации по­лиморфизма в Object Pascal используются динамические мето­ды. По возможностям наследования и перекрытия они анало­гичны виртуальным методам, но доступ к ним выполняется через таблицу динамических методов (ТДМ). ТДМ хранит адре­са только тех динамических методов, которые определены в данном классе. Такой подход позволяет снизить расход памяти при большом количестве этих методов и самих классов.

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

Для объявления метода динамическим используется дирек­тива dynamic. Перекрытие динамических методов производит­ся так же, как и виртуальных — с использованием ключевого слова override.

Абстрактные методы

Абстрактные методы используются при объявлении мето­дов, реализация которых откладывается. Такие методы в клас­се описываются служебным словом abstract и обязательно пере­определяются в потомках класса.

Класс, в состав которого входят методы с отложенной реали­зацией, называется абстрактным. Создавать объекты абстракт­ных классов запрещается.

Упражнение 1.3.4. Разработайте родительский класс для ри­сования геометрических фигур.

Решение

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

Скрыть;

Задать новое расположение геометрической фигуры;

Отобразить;

Методы скрыть и отобразить для каждой геометрической фигуры будут определять по-своему, поэтому необходимо объя­вить их виртуальными и абстрактными:

Туре

TPosition = class private

Fx, Fy : integer; public

constructor Create (InitX, InitY: Integer);

function GetX: integer;

function GetY: integer;

destructor Destroy; end;

TGeometricalFigure = class (TPosition) private

Fcolor: word; public

constructor Create(InitX, InitY: integer; InitColor: word);

destructor Destroy;

function GetColor: word;

procedure SetColor(NewColor: word);

procedure Show; virtual; abstract;

procedure Hide; virtual; abstract;

Procedure Move(NewX, NewY: integer); end;

Параллелизм — свойство нескольких абстракций одновре­менно находиться в активном состоянии, т. е. выполнять неко­торые операции.

Есть задачи, в которых автоматические системы должны обра­батывать много событий одновременно. В других случаях потреб­ность в вычислительной мощности превышает ресурсы одного процессора. В каждой из таких ситуаций естественно использо­вать несколько компьютеров для решения задачи или задейст­вовать многозадачность на многопроцессорном компьютере.

Процесс — это фундаментальная единица действия в систе­ме. Каждая программа имеет по крайней мере один поток управления, параллельная система, имеет много таких пото­ков: длительность существования одних недолго, а другие жи­вут в течение всего сеанса работы системы. Реальная паралле­льность достигается только на многопроцессорных системах, а системы с одним процессором имитируют параллельность за счет алгоритмов разделения времени.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19