Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP / books / Osnovi objektno-orientirovannogo programmirovaniya.pdf
Скачиваний:
62
Добавлен:
03.03.2016
Размер:
9.04 Mб
Скачать

Глобальная структура наследования

Ранее мы уже ссылались на универсальные (universal) классы GENERAL и ANY, а также на безобъектный (objectless) класс NONE. Пришло время пояснить их роль и представить глобальную структуру наследования.

Универсальные классы

Удобно использовать следующее соглашение:

Правило Универсального Класса

Любой класс, не содержащий предложение наследования, неявно содержит предложение вида:

inherit ANY,

ссылающееся на класс ANY из библиотеки Kernel.

Тем самым становится возможным определить по умолчанию целый ряд компонентов, наследуемых всеми классами. Эти компоненты реализуют общие, универсальные операции: копирование, клонирование, сравнение, базовый ввод и вывод.

Для большей гибкости поместим эти компоненты в класс GENERAL, чьим потомком является ANY. Сам класс ANY по умолчанию не имеет никаких компонентов, будучи классом вида: class ANY inherit GENERAL end. При создании нового проекта его менеджер может решить, какие общие для проекта компоненты следует включить в класс ANY, в то время как GENERAL остается всегда неизменным.

|Для построения нетривиального ANY можно прибегнуть к наследованию. В самом деле, класс ANY можно породить от некоторого HOUSE_STYLE или нескольких таких классов, не вводя циклы в иерархию наследования и не нарушая правило об универсальном классе: достаточно сделать класс HOUSE_STYLE и другие классы потомками GENERAL. Вынесенный на рис. 16.4 текст "Классы разработчика" означает все классы, написанные разработчиком и не порожденные от GENERAL явным образом. |

Рис. 16.4. Глобальная структура наследования

Нижняя часть иерархии

На рис. 16.4 представлен также класс NONE, антипод класса ANY, потомок всех классов, не имеющих собственных наследников и превращающий глобальную иерархию наследования классов в решетку (математическую структуру). NONE не имеет потомков, его нельзя переопределить - это лишь удобная фикция, однако, теоретическое существование такого класса оправдано и служит двум практическим целям:

*Void - пустая ссылка, используемая наряду с другими ссылками, по соглашению имеет тип NONE. (Фактически, Void -это один из компонентов класса GENERAL.)

*Чтобы скрыть компонент от всех клиентов, достаточно экспортировать его только классу NONE. Предложение feature {NONE} (практически эквивалентное feature {}, но записанное явно) или предложение наследования export {NONE} (на практике дающее тот же результат, что

иexport {} ), делает компонент недоступным для любого класса, написанного разработчиком,

ибо NONE не имеет потомков. Обратите внимание на то, что NONE скрывает и все свои компоненты.

Первое свойство объясняет, почему значение Void можно присвоить любому элементу ссылочного типа данных. До сих пор статус Void оставался некой загадкой, теперь, когда Void связано с классом NONE, этот статус становится очевидным, официальным и согласующимся с системой типов: по построению NONE является потомком всех классов, а потому мы можем использовать Void как допустимое значение любой ссылки, не нарушая правил описания типов.

По симметрии ко второму свойству заметим, что объявление, начинающееся с feature и экспортирующее все компоненты во все классы, написанные разработчиком, считается сокращением от feature {ANY}. Для повторного экспорта во все классы компонента родителя, доступ к которому был ограничен, можно использовать предложение export {ANY} или его не столь очевидное сокращение export.

Классы ANY и NONE обеспечивают замкнутость системы типов и полноту структуры наследования: решетка (это строго определенный математический термин) имеет свой верхний и нижний элемент.

Универсальные компоненты

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

*clone для создания клона (дубля) объекта, а также его "глубинный" вариант deep_clone для рекурсивного дублирования полной структуры объекта;

*copy для копирования содержимого одного объекта в другой;

*equal для сравнения объектов (поле-с-полем), а также его "глубинный" вариант deep_equal ;

*print и print_line - печать простого представления по умолчанию любого объекта (default representation);

*tagged_out - строка, содержащая представление по умолчанию любого объекта, в котором каждое поле сопровождается своей меткой (tag) (соответствующим именем атрибута);

*same_type и conforms_to - булевы функции, сопоставляющие тип текущего объекта с типом другого;

*generator - возвращает имя порождающего (generating) класса объекта, то есть класса, экземпляром которого является данный объект.

Соседние файлы в папке books