Опубликован: 22.11.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Тверской государственный университет
Лекция 19:

Интерфейсы. Множественное наследование

Наследование от общего предка

Проблема наследования от общего предка характерна, в первую очередь, для множественного наследования классов. Если класс C является наследником классов A и B, а те, в свой черед, являются наследниками класса Parent, то класс наследует свойства и методы своего предка Parent дважды, один раз получая их от класса A, другой от - B. Это явление называется еще дублирующим наследованием. Для классов ситуация осложняется тем, что классы A и B могли по-разному переопределить методы родителя и для потомков предстоит сложный выбор реализации.

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

Начнем наш пример с наследования интерфейсов:

public interface IParent
{
	void ParentMethod();
}
public interface ISon1:IParent
{
	void Son1Method();
}
public interface ISon2:IParent
{
	void Son2Method();
}

Два сыновних интерфейса наследуют метод своего родителя. А теперь рассмотрим класс, наследующий оба интерфейса:

public class Pars:ISon1, ISon2
{
	public void ParentMethod()
	{
		Console.WriteLine("Это метод родителя!");
	}
	public void Son1Method()
	 {
		 Console.WriteLine("Это метод старшего сына!");
	 }
	public void Son2Method()
	{
		Console.WriteLine("Это метод младшего сына!");
	}
}//class Pars

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

public void TestIParsons()
{
	Console.WriteLine("Объект класса вызывает методы трех 
		интерфейсов!");
	Cli.Pars ct = new Cli.Pars();
	ct.ParentMethod();
	ct.Son1Method();
	ct.Son2Method();
	Console.WriteLine("Интерфейсный объект 1 вызывает свои 
		методы!");
	Cli.IParent ip = (IParent)ct;
	ip.ParentMethod();
	Console.WriteLine("Интерфейсный объект 2 вызывает свои 
		методы!");
	Cli.ISon1 ip1 = (ISon1)ct;
	ip1.ParentMethod();
	ip1.Son1Method();
	Console.WriteLine("Интерфейсный объект 3 вызывает свои 
		методы!");
	Cli.ISon2 ip2 = (ISon2)ct;
	ip2.ParentMethod();
	ip2.Son2Method();
}

Результаты работы тестирующей процедуры показаны на рис. 19.3.

Дублирующее наследование интерфейсов

Рис. 19.3. Дублирующее наследование интерфейсов

Встроенные интерфейсы

Рассмотрим несколько встроенных интерфейсов, являющихся частью библиотеки FCL. Они используются многими классами-библиотеками так же, как и классами, создаваемыми пользователем.

Александр Галабудник
Александр Галабудник

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

Александра Гусева
Александра Гусева
Сергей Кузнецов
Сергей Кузнецов
Россия, Москва
Pavel Kuchugov
Pavel Kuchugov
Россия, Московский инженерно-физический институт, 2010