Опубликован: 23.10.2005 | Доступ: свободный | Студентов: 4086 / 201 | Оценка: 4.44 / 4.19 | Длительность: 33:04:00
Специальности: Программист
Дополнительный материал 2:

Универсальность и (versus) наследование

< Дополнительный материал 1 || Дополнительный материал 2: 123456

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

Теперь от универсальности в чистом виде можно перейти к наследованию. Для сравнения его с универсальностью рассмотрим пример из стандартной библиотеки для работы с файлами. Начнем с эскиза реализации "специальных файлов" в смысле 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.

< Дополнительный материал 1 || Дополнительный материал 2: 123456