Построение иерархии интерфейсов
Построение иерархии интерфейсов
Продолжим наше обсуждение вопросов создания пользовательских интерфейсов и рассмотрим тему иерархии интерфейсов. Вы знаете, что класс может выступать в роли базового класса для других классов (которые, в свою очередь, тоже могут быть базовыми классами для других классов), но точно так же можно строить отношения наследования и среди интерфейсов. Как и следует ожидать, интерфейс на вершине иерархии определяет общее поведение, а интерфейсы, находящиеся на более низких уровнях, "уточняют" это поведение. Для примера рассмотрите следующую иерархию интерфейсов.
// Базовый интерфейс.
public interface IDrawable { void Draw(); }
public interface IPrintable: IDrawable { void Print(); }
public interface IMetaFileRender: IPrintable { void Render(); }
Соответствующая цепочка наследования показана на рис. 7.5.
Рис. 7.5. Иерархия интерфейсов
Теперь, если некоторый класс должен поддерживать все варианты поведения, заданные в рамках этой иерархии интерфейсов, то этот класс должен выводиться из интерфейса, лежащего в основе иерархии (в данном случае это IMetaFileRender). Все методы, определенные базовым интерфейсом (или интерфейсами), автоматически переносятся в определение. Например:
// Этот класс поддерживает IDrawable, IPrintable и IMetaFileRender.
public class SuperImage: IMetaFileRender {
public void Draw() { Console.WriteLine("Базовая логика визуализации."); }
public void Print() { Console.WriteLine("Вывод на принтер."); }
public void Render() { Console WriteLine("Вывод в метафайл."); }
}
Вот пример вывода каждого интерфейса из экземпляра SuperImage.
// Использование интерфейсов.
static void Main(string[] args) {
SuperImage si = new SuperImage();
// Получение IDrawable.
IDrawable itfDraw = (IDrawable)si;
itfDraw.Draw();
// Получение IMetaFileRender, который использует все методы,
// определенные выше по цепочке интерфейсов.
if (itfDraw is IMetaFileRender) {
IMetaFileRender itfMF = (IMetaFileRender)itfDraw;
itfMF.Render();
itfMF.Print();
}
Console.ReadLine();
}