Продолжим наше обсуждение вопросов создания пользовательских интерфейсов и рассмотрим тему
// Базовый интерфейс.
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();
}
Интерфейсы с множеством базовых интерфейсов
При построении иерархии интерфейсов вполне допустимо создавать интерфейсы, которые оказываются производными от нескольких базовых интерфейсов. Однако напомним, что
public interface ICar { void Drive(); }
public interface IUnderwaterCar { void Dive(); }
// Здесь интерфейс имеет ДВА базовых интерфейса.
public interface IJamesBondCar: ICar, IUnderwaterCar { void TurboBoost(); }
На рис. 7.6 показана соответствующая цепочка интерфейсов.
Рис. 7.6. Общая система типов (CTS) допускает множественное наследование интерфейсных типов
При построении класса, реализующего IJamesBondCar (машина Джеймса Бонда), вы должны реализовать TurboBoost(), Dive() и Drive().
public class JamesBondCar: IJamesBondCar {
public void Drive() { Console.WriteLine("Ускорение…"); }
public void Dive() { Console.WriteLine("Погружение…"); }
public void TurboBoost() { Console.WriteLine{"Взлет!"); }
}
Этот специализированный автомобиль можно использовать так, как и ожидается.
static void Main(string[] args) {
…
JamesBоndCar j = new JamesBondCar();
j.Drive();
j.TurboBoost();
j.Dive();
}
Реализация интерфейсов в Visual Studio 2005