Интерфейсы C#

Интерфейсы C#

Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье вы узнали про статические поля и методы в C#. В данной статье я бы хотел поговорить про интерфейсы в C#. При наследовании в C# в качестве родительского класса можно указать один и только один класс. Это не всегда бывает удобно. Для решения данной проблемы в C# вводится понятие интерфейса. В интерфейсе описываются только заголовки методов. Когда мы создаём класс, то можем указать, что данный класс реализует один интерфейс или сразу несколько.

Когда класс говорит, что он реализует какой-то интерфейс, класс гарантирует что внутри него (класса) реализованы все методы, которые описаны в интерфейсе. Интерфейс — это контракт, который необходимо исполнить классом.

Особенности интерфейсов:

  1. Только заголовки методов.
  2. Реализация методов отсутствует.
  3. Нельзя создать экземпляр интерфейса, однако, можно создать переменную типа интерфейса, ведь это ссылочный тип данных. Такая переменная может указывать на объект класса, реализующего данный интерфейс.
  4. Перед методом не нужно ставить "public", т.к. метод в интерфейс по умолчанию является "public" и "virtual".

Интерфейс может быть реализован также структурами.

Интерфейс создаётся с помощью ключевого слова "interface". Перед ключевым словом можно указать "public" или "internal" (по умолчанию, если ничего не указано):

public interface IFlyable {

}

Что можно описать внутри интерфейсов:

  1. Заголовки методов.
  2. Можно описать свойства (properties), т.е. они не являются полями, это методы "get" и "set".
  3. Индексатор (индексирующее property), т.к. это тоже метод.
  4. Делегаты.

Как записать, что класс реализует интерфейс:

public class Animal: IFlyable {

}

В данном случае мы указали, что класс "Animal" реализует интерфейс "IFlyable".

Если класс-родитель реализует какой-либо интерфейс, то считается, что и класс-наследник реализует данный интерфейс. В классе-наследнике реализацию можно переопределить.
По рекомендации Microsoft перед названием всех интерфейсов нужно ставить букву "I". Технически, конечно, и без этого всё будет работать.

Интерфейс можно реализовать двумя способами:

1) Напрямую в классе, просто реализуя метод.

2) Прямая реализация метода интерфейса. В данном случае в классе создаётся метод, у которого не указывается уровень доступа, в качестве имени метода идёт имя интерфейса и имя метода. Это приведёт к тому, что не получится вызвать этот метод через ссылку самого объекта класса, можно вызывать только через ссылку типа интерфейса.

Интересный момент заключается в том, что можно сделать сразу двумя способами, причем по-разному реализовав, и это не будет перегрузкой, т.к. параметры будут одни и те же (и одного и того же типа). Вызов данных методов зависит от типа ссылки, через которую они вызываются. В реальности обычно так не делают. Зачем так сделали мне, лично, непонятно.

Давайте на примере рассмотрим, как создавать и реализовывать интерфейсы:

// Что-то что летает
public interface IFlyable
{
  void fly();
}

// Животное, которое может летать
public class Bird : IFlyable
{
  // 1 способ реализации интерфейса
  public void fly()
  {
    Console.WriteLine("Птица полетела...");
  }
  // 2 способ реализации интерфейса
  void IFlyable.fly()
  {
    Console.WriteLine("Птица не полетела. Странно...");
  }
}
class Program
{
  static void Main(string[] args)
  {
    // Создадим переменную класса Bird
    Bird bird1 = new Bird();
    bird1.fly(); // выйдет "Птица полетела..."
    // Создадим переменную типа IFlyable
    IFlyable bird2 = new Bird();
    bird2.fly(); // выйдет "Птица не полетела. Странно..."
    // Если мы закоментируем метод "void IFlyable.fly()", то птица в обоих случаях полетит
    Console.ReadLine();
  }
}

Существует набор уже готовых интерфейсов, которые бывает полезно реализовать в собственных классах. Например, интерфейс "IComparable", который состоит из одного единственного метода "int CompareTo(Object obj)". Данный интерфейс даёт возможность сортировки объектов в коллекции. Для сортировки нужно уметь сравнивать 2 значения. Если это строки или числа, то здесь вопросов нет, а вот с объектами непонятно. Как сравнить, что один объект больше другого? А это вы сами должны описать в реализации этого интерфейса.

Существует также интерфейс "IComparer", который сравнивает 2 объекта. В нём также один метод "int Compare (Object obj1, Object obj2)".

В качестве домашнего задания: попробуйте в класс "Room", который мы создали на одном из прошлых занятий по C#, добавить реализацию интерфейса "IComparable". Также создайте статический класс, который будет реализовывать интерфейс "IComparer". В качестве сравнения используйте площадь комнат.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *