Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по ая.docx
Скачиваний:
22
Добавлен:
20.09.2019
Размер:
276.66 Кб
Скачать

Абстрактные классы

Методы класса могут быть объявлены как абстрактные. Это означает, что в этом классе нет реализации этих методов. Абстрактные методы пишутся с модификатором abstract. Класс, в котором есть хотя бы один абстрактный метод, называется абстрактным (в таком классе могу быть и обычные методы). Нельзя создавать экземпляры абстрактного класса — такой класс может использоваться только в качестве базового класса для других классов. Для потомка такого класса есть две возможности — или он реализует все абстрактные методы базового класса (и в этом случае для такого класса-потомка мы сможем создавать его экземпляры), или реализует не все абстрактные методы базового класса (в этом случае он является тоже абстрактным классом, и единственная возможность его использования — это производить от него классы потомки). Рассмотрим пример:

abstract class Ferst

{

public abstract void Method1();

public abstract void Method2(string str);

}

class Second : Ferst

{

public override void Method1()

{

Console.WriteLine("Ferst Method");

}

public override void Method2(string str)

{

Console.WriteLine(str);

}

}

class Program

{

static void Main()

{

Second s = new Second();

s.Method1();

s.Method2("Hello");

Console.WriteLine();

}

}

В приведенном примере создан абстрактный класс Ferst, с двумя абстрактными методами. Класс Second наследуется от абстрактного класса Ferst и реализует определенные в абстрактном классе методы.

Классы без потомков

Экзотическим, но иногда полезным видом классов являются классы, для которых запрещается строить классы потомки путем наследования. При создании такого класса нет необходимости в выполнении над классом каких-либо болезненных операций. Вполне достаточно приписать классу модификатор sealed, он и запрещает построение потомков.

Интерфейсы

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

Интерфейсы позволяют частично справиться с таким существенным недостатком языка, как отсутствие множественного наследования классов. Хотя реализация множественного наследования сталкивается с рядом проблем, его отсутствие существенно снижает выразительную мощь языка. В языке 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, обеспечивающими доступ к полю, тем самым обойдя ограничение на объявление полей.