logo
Лекции по ая

Интерфейсы

В таком понимании интерфейс - это частный случай класса. Интерфейс представляет собой полностью абстрактный класс, все методы которого абстрактны. От абстрактного класса интерфейс отличается некоторыми деталями в синтаксисе и поведении. Синтаксическое отличие состоит в том, что методы интерфейса объявляются без указания модификатора доступа. Отличие в поведении заключается в более жестких требованиях к потомкам. Класс, наследующий интерфейс, обязан полностью реализовать все методы интерфейса. В этом отличие от класса, наследующего абстрактный класс, где потомок может реализовать лишь некоторые методы родительского абстрактного класса, оставаясь абстрактным классом.

Интерфейсы позволяют частично справиться с таким существенным недостатком языка, как отсутствие множественного наследования классов. Хотя реализация множественного наследования сталкивается с рядом проблем, его отсутствие существенно снижает выразительную мощь языка. В языке C# полного множественного наследования классов нет. Чтобы частично сгладить этот пробел, допускается множественное наследование интерфейсов. Обеспечить возможность классу иметь несколько родителей - один полноценный класс, а остальные в виде интерфейсов, - в этом и состоит основное назначение интерфейсов.

Интерфейсы содержат методы, свойства, события, индексаторы или любое сочетание этих перечисленных типов членов. Интерфейс не может содержать константы, поля, операторы, конструкторы экземпляров, деструкторы или типы. Он не может содержать статические члены. Члены интерфейсов автоматически являются открытыми, и они не могут включать никакие модификаторы доступа. Интерфейсы отвечают на вопрос "Как это должно работать?" или "Как это должно выглядеть?". Интерфейсы определяются с помощью ключевого слова interface.

При реализации множественного наследования интересов может возникнуть ситуация когда два интерфейса имеют метод с одинаковым названием. Если в этом случае реализация метода зависит от конкретного интерфейса, то перед методом в классе реализации необходимо написать имя интерфейса. При этом нельзя использовать модификатор Public. При создании объекта класса соответственно перед выполнением необходимо выполнить проверку при помощи оператора is, для определения какой метод наследует интерфейс, для определения какой метод выполнять. Рассмотрим пример множественого наследования.

interface MyInterface1

{

void MyMethod();

}

interface MyInterface2

{

void MyMethod();

}

class MyClass : MyInterface1, MyInterface2

{

void MyInterface1.MyMethod()

{

Console.WriteLine("My Ferst Interface");

}

void MyInterface2.MyMethod()

{

Console.WriteLine("My Second Interface");

}

public void MyMethod()

{

Console.WriteLine("My Class");

}

}

class Program

{

static void Main()

{

MyClass m = new MyClass();

m.MyMethod();

if (m is MyInterface1)

{

MyInterface1 tmp1 = (MyInterface1)m;

tmp1.MyMethod();

}

if (m is MyInterface2)

{

MyInterface2 tmp2 = (MyInterface2)m;

tmp2.MyMethod();

}

Console.ReadLine();

}

}

В приведенном примере создано два интерфейса MyInterface1 и MyInterface2 и класс их наследующий MyClass. В обоих интерфейсах определен метод MyMethod(). В нашем классе данный метод определен три раза, два из которых для конкретной реализации интерфейса. При выполнении данного метода в зависимости от контекста объекта будет меняться и результат выполнения.

В интерфейсе можно объявить метод-свойство с процедурами get и set, обеспечивающими доступ к полю, тем самым обойдя ограничение на объявление полей.