Основы объектно-ориентированного проектирования

         

Наследование


Теперь от универсальности в чистом виде можно перейти к наследованию. Для сравнения его с универсальностью рассмотрим пример из стандартной библиотеки для работы с файлами. Начнем с эскиза реализации "специальных файлов" в смысле Unix, то есть файлов, связанных с устройствами:

class DEVICE feature open (file_descriptor: INTEGER) is do ... end close is do ... end opened: BOOLEAN end

Пример использования этого класса:

d1: DEVICE; f1: INTEGER; ... create d1.make; d1.open (f1); if d1.opened then ...

Теперь рассмотрим понятие ленточного накопителя. Это устройство обладает всеми свойствами, представленными в классе DEVICE, плюс способность перематывать ленту. Вместо формирования нового класса на пустом месте можно использовать наследование и объявить класс TAPE, расширяя и модифицируя DEVICE. Новый класс расширяет DEVICE, добавляя новую процедуру rewind в соответствии с особенностями именно ленточных устройств. Кроме того необходима новая версия open, модифицированная с учетом специфики накопителей на магнитной ленте.

Объекты типа TAPE автоматически обладают всеми свойствами объектов DEVICE плюс их собственные (перемотка). Придется модифицировать ряд компонентов DEVICE в классе TAPE (open) и добавить новые (rewind). Класс DEVICE может иметь и других потомков, например класс DISK с его собственными специфическими особенностями прямого доступа.

Наследованию сопутствует полиморфизм, разрешая присваивания x:= y, если тип x - предок типа y. Следующая особенность - динамическое связывание: если x устройство, то вызов x.open (f1) будет выполнен различным образом в зависимости от значения присвоенного x перед вызовом. После присваивания x := y, где y - лента, будет выполнена версия открытия для ленты.

Как уже указывалось, преимуществами наследования являются возможность повторного использования и расширяемость. Ключевым является принцип Открыт-Закрыт: программный элемент типа DEVICE пригоден как для непосредственного использования, так и в качестве предка новых классов.


Далее следуют отложенные компоненты и классы. Нужно отметить, что устройства Unix являются файлами специального типа, поэтому DEVICE может быть потомком класса FILE, другими потомками которого могут быть TEXT_FILE и BINARY_FILE. На рис. B.1 приведен граф наследования, в данном случае дерево наследования.


Рис. B.1.  Простая иерархия наследования с отложенными и эффективными классами

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

deferred class FILE feature open (file_descriptor: INTEGER) is deferred end close is deferred end; endЭффективные потомки FILE обеспечат реализацию open и close.


Содержание раздела