Шрифт:
Если вы захотите построить класс с именем SuperImage (суперизображение), поддерживающий базовую визуализацию (IDraw), 3D-визуализацию (IDraw3D), а также сервис печати (IDrawToPrinter), то единственным способом обеспечить уникальную реализацию для каждого метода будет использование явной реализации интерфейса.
Исходный код. Проект CustomInterface размешен в подкаталоге, соответствующем главе 7.
Построение иерархии интерфейсов
Продолжим наше обсуждение вопросов создания пользовательских интерфейсов и рассмотрим тему иерархии интерфейсов. Вы знаете, что класс может выступать в роли базового класса для других классов (которые, в свою очередь, тоже могут быть базовыми классами для других классов), но точно так же можно строить отношения наследования и среди интерфейсов. Как и следует ожидать, интерфейс на вершине иерархии определяет общее поведение, а интерфейсы, находящиеся на более низких уровнях, "уточняют" это поведение. Для примера рассмотрите следующую иерархию интерфейсов.
Соответствующая цепочка наследования показана на рис. 7.5.
Рис. 7.5. Иерархия интерфейсов
Теперь, если некоторый класс должен поддерживать все варианты поведения, заданные в рамках этой иерархии интерфейсов, то этот класс должен выводиться из интерфейса, лежащего в основе иерархии (в данном случае это IMetaFileRender). Все методы, определенные базовым интерфейсом (или интерфейсами), автоматически переносятся в определение. Например:
Вот пример вывода каждого интерфейса из экземпляра SuperImage.
Интерфейсы с множеством базовых интерфейсов
При построении иерархии интерфейсов вполне допустимо создавать интерфейсы, которые оказываются производными от нескольких базовых интерфейсов. Однако напомним, что нельзя строить классы, которые будут производными от нескольких базовых классов. Для примера предположим, что вы строите набор интерфейсов, моделирующих поведение автомобиля.
На рис. 7.6 показана соответствующая цепочка интерфейсов.
Рис. 7.6. Общая система типов (CTS) допускает множественное наследование интерфейсных типов