СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до 19.05.2025

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Интерфейсы в языке C#

Категория: Информатика

Нажмите, чтобы узнать подробности

Данный методический материал содержит презентацию к уроку "Интерфейсы в языке С#". Материал предназначен для подготовки к занятиям по данной теме, а также  для студентов, изучающих язык С# в дисциплинах "Основы алгоритмизации и программирования" и "Прикладное программирование". 

Просмотр содержимого документа
«Интерфейсы в языке C#»

Интерфейсы: назначение, правила написания. Способы реализации интерфейсов. Работа с объектами через интерфейсы. Операторы is и as.

Интерфейсы: назначение, правила написания. Способы реализации интерфейсов.

Работа с объектами через интерфейсы. Операторы is и as.

Интерфейс представляет ссылочный тип, который может определять некоторый функционал (набор методов и свойств без реализации). Затем этот функционал реализуют классы и структуры, которые применяют данные интерфейсы. Для определения интерфейса используется ключевое слово  interface . Названия интерфейсов в C# начинаются с заглавной буквы  I , например, IComparable, IEnumerable (так называемая венгерская нотация), однако это не обязательное требование , а стиль программирования . Интерфейсы могут определять следующие сущности: Методы Свойства Индексаторы События Статические поля и константы (начиная с версии C# 8.0) Интерфейсы не могут определять переменные.

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

Для определения интерфейса используется ключевое слово  interface . Названия интерфейсов в C# начинаются с заглавной буквы  I , например, IComparable, IEnumerable (так называемая венгерская нотация), однако это не обязательное требование , а стиль программирования .

Интерфейсы могут определять следующие сущности:

  • Методы
  • Свойства
  • Индексаторы
  • События
  • Статические поля и константы (начиная с версии C# 8.0)

Интерфейсы не могут определять переменные.

Например, простейший интерфейс, который определяет все эти компоненты: interface IMovable {      // константа      const int minSpeed = 0;     // минимальная скорость      // статическая переменная      static int maxSpeed = 60;   // максимальная скорость      // метод      void Move();                // движение      // свойство      string Name { get; set; }   // название      delegate void MoveHandler(string message);  // определение делегата для события      // событие      event MoveHandler MoveEvent;    // событие движения }

Например, простейший интерфейс, который определяет все эти компоненты:

interface IMovable

{

     // константа

     const int minSpeed = 0;     // минимальная скорость

     // статическая переменная

     static int maxSpeed = 60;   // максимальная скорость

     // метод

     void Move();                // движение

     // свойство

     string Name { get; set; }   // название

     delegate void MoveHandler(string message);  // определение делегата для события

     // событие

     event MoveHandler MoveEvent;    // событие движения

}

В примере определен интерфейс IMovable, который представляет некоторый движущийся объект. Данный интерфейс содержит различные компоненты, которые описывают возможности движущегося объекта. То есть интерфейс описывает некоторый функционал, который должен быть у движущегося объекта. Методы и свойства интерфейса могут не иметь реализации, в этом они сближаются с абстрактными методами и свойствами абстрактных классов. В данном случае интерфейс определяет метод Move, который будет представлять некоторое передвижение. Он не имеет реализации, не принимает никаких параметров и ничего не возвращает. То же самое в данном случае касается свойства Name - это определение свойства в интерфейсе, которое не имеет реализации.

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

Методы и свойства интерфейса могут не иметь реализации, в этом они сближаются с абстрактными методами и свойствами абстрактных классов.

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

То же самое в данном случае касается свойства Name - это определение свойства в интерфейсе, которое не имеет реализации.

При объявлении интерфейса, если его члены (методы и свойства) не имеют модификаторов доступа, то по умолчанию доступ  public , так как цель интерфейса - определение функционала для реализации его классом. Это касается также и констант и статических переменных, которые в классах и структурах по умолчанию имеют модификатор private . В интерфейсах же они имеют по умолчанию модификатор public . Например, мы могли бы обратиться к константе minSpeed и переменной maxSpeed интерфейса IMovable: static void Main(string[] args) {      Console.WriteLine(IMovable.maxSpeed);      Console.WriteLine(IMovable.minSpeed); }

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

Например, мы могли бы обратиться к константе minSpeed и переменной maxSpeed интерфейса IMovable:

static void Main(string[] args)

{

     Console.WriteLine(IMovable.maxSpeed);

     Console.WriteLine(IMovable.minSpeed);

}

Начиная с версии C# 8.0, можно явно указывать модификаторы доступа у компонентов интерфейса: interface IMovable {      public const int minSpeed = 0;     // минимальная скорость      private static int maxSpeed = 60;   // максимальная скорость      public void Move();      protected internal string Name { get; set; }    // название      public delegate void MoveHandler(string message);  // //определение делегата для события      public event MoveHandler MoveEvent;    // событие движения } Начиная с версии C# 8.0 интерфейсы поддерживают реализацию методов и свойств по умолчанию. Можно определить в интерфейсах методы и свойства, которые имеют реализацию как в обычных классах и структурах.

Начиная с версии C# 8.0, можно явно указывать модификаторы доступа у компонентов интерфейса:

interface IMovable

{

     public const int minSpeed = 0;     // минимальная скорость

     private static int maxSpeed = 60;   // максимальная скорость

     public void Move();

     protected internal string Name { get; set; }    // название

     public delegate void MoveHandler(string message);  // //определение делегата для события

     public event MoveHandler MoveEvent;    // событие движения

}

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

Например, определим реализацию метода Move по умолчанию: interface IMovable {      // реализация метода по умолчанию      void Move()      {          Console.WriteLine(

Например, определим реализацию метода Move по умолчанию:

interface IMovable

{

     // реализация метода по умолчанию

     void Move()

     {

         Console.WriteLine("Walking");

     }

}

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

interface IMovable {      void Move()      {          Console.WriteLine(

interface IMovable

{

     void Move()

     {

         Console.WriteLine("Walking");

     }

     // реализация свойства по умолчанию

     // свойство только для чтения

     int MaxSpeed { get { return 0; } }

}

Если интерфейс имеет приватные методы и свойства (то есть с модификатором private), то они должны иметь реализацию по умолчанию. Это относится к любым статическим методам и свойствам (не обязательно приватным):

distance / speed;      static int MaxSpeed      {          get { return maxSpeed; }          set          {              if (value 0) maxSpeed = value;          }      } } " width="640"

interface IMovable

{

     public const int minSpeed = 0;     // минимальная скорость

     private static int maxSpeed = 60;   // максимальная скорость

         // находим время, за которое надо пройти расстояние distance со скоростью speed

     static double GetTime(double distance, double speed) = distance / speed;

     static int MaxSpeed

     {

         get { return maxSpeed; }

         set

         {

             if (value 0) maxSpeed = value;

         }

     }

}

class Program {      static void Main(string[] args)      {          Console.WriteLine(IMovable.MaxSpeed);          IMovable.MaxSpeed = 65;          Console.WriteLine(IMovable.MaxSpeed);          double time = IMovable.GetTime(100, 10);          Console.WriteLine(time);      } } Модификаторы доступа интерфейсов Интерфейсы по умолчанию имеют уровень доступа  internal , то есть такой интерфейс доступен только в рамках текущего проекта. Но с помощью модификатора public мы можем сделать интерфейс общедоступным:

class Program

{

     static void Main(string[] args)

     {

         Console.WriteLine(IMovable.MaxSpeed);

         IMovable.MaxSpeed = 65;

         Console.WriteLine(IMovable.MaxSpeed);

         double time = IMovable.GetTime(100, 10);

         Console.WriteLine(time);

     }

}

Модификаторы доступа интерфейсов

Интерфейсы по умолчанию имеют уровень доступа  internal , то есть такой интерфейс доступен только в рамках текущего проекта. Но с помощью модификатора public мы можем сделать интерфейс общедоступным:

 New Item...   и в диалоговом окне добавления нового компонента выбрать пункт   Interface . " width="640"

public interface IMovable

{

     void Move();

}

В Visual Studio есть специальный компонент для добавления нового интерфейса в отдельном файле. Для добавления интерфейса в проект можно нажать правой кнопкой мыши на проект и в появившемся контекстном меню выбрать  Add -  New Item...   и в диалоговом окне добавления нового компонента выбрать пункт   Interface .

Реализация интерфейса  Чтобы указать, что класс реализует интерфейс, необходимо, после имени класса и двоеточия указать имя интерфейса:   class SomeClass : ISomeInterface // реализация интерфейса //ISomeInterface  {     // тело класса  } Класс, который реализует интерфейс, должен предоставить реализацию всех членов интерфейса: class SomeClass : ISomeInterface  {     public string SomeProperty     {       get       { …. }

Реализация интерфейса

Чтобы указать, что класс реализует интерфейс, необходимо, после имени класса и двоеточия указать имя интерфейса:

class SomeClass : ISomeInterface // реализация интерфейса //ISomeInterface {    // тело класса }

Класс, который реализует интерфейс, должен предоставить реализацию всех членов интерфейса:

class SomeClass : ISomeInterface {    public string SomeProperty    {      get      { …. }

     set       {         …       }     }     public void SomeMethod(int a)     {       // тело метода     }  } Пример: Есть классы геометрических фигур  Прямоугольник  и  Окружность . У обоих классов должны быть методы вычисления периметра и площади. Эти методы мы представим интерфейсом :

     set      {        …

      }    }    public void SomeMethod(int a)    {      // тело метода    } }

Пример: Есть классы геометрических фигур  Прямоугольник  и  Окружность . У обоих классов должны быть методы вычисления периметра и площади. Эти методы мы представим интерфейсом :

 interface IGeometrical // объявление интерфейса  {     void GetPerimeter();     void GetArea ();  }  class Rectangle : IGeometrical //реализация интерфейса  {     public void GetPerimeter()     {       Console.WriteLine(

interface IGeometrical // объявление интерфейса {    void GetPerimeter();    void GetArea (); } class Rectangle : IGeometrical //реализация интерфейса {    public void GetPerimeter()    {      Console.WriteLine("(a+b)*2");    }    public void GetArea()    {      Console.WriteLine("a*b");    } }

 class Circle : IGeometrical //реализация интерфейса  {     public void GetPerimeter()     {       Console.WriteLine(

class Circle : IGeometrical //реализация интерфейса {    public void GetPerimeter()    {      Console.WriteLine("2*pi*r");    }    public void GetArea()    {      Console.WriteLine("pi*r^2");    } } class Program {    static void Main(string[] args)    {      List figures = new List();      figures.Add(new Rectangle());      figures.Add(new Circle());      foreach (IGeometrical f in figures)      {        f.GetPerimeter();        f.GetArea();      }      Console.ReadLine();    } }

 Множественное наследование  – это когда один класс сразу наследуется от нескольких классов. Но бывает так, что базовые классы содержат методы с одинаковыми именами, в результате чего возникают определенные неточности и ошибки.  Множественное наследование есть в языке C++, а в C# от него отказались и вместо этого ввели интерфейсы.  В C# класс может реализовать сразу несколько интерфейсов. Это и является главным отличием использования интерфейсов и абстрактных классов. Кроме того, абстрактные классы могут содержать все остальные члены, которых не может быть в интерфейсе, и не все методы/свойства в абстрактном классе должны быть_абстрактными.    Если класс реализует несколько интерфейсов, они разделяются_запятыми:

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

Множественное наследование есть в языке C++, а в C# от него отказались и вместо этого ввели интерфейсы.

В C# класс может реализовать сразу несколько интерфейсов. Это и является главным отличием использования интерфейсов и абстрактных классов. Кроме того, абстрактные классы могут содержать все остальные члены, которых не может быть в интерфейсе, и не все методы/свойства в абстрактном классе должны быть_абстрактными.

Если класс реализует несколько интерфейсов, они разделяются_запятыми:

 interface IDrawable  {     void Draw();  }   interface IGeometrical  {     void GetPerimeter();     void GetArea ();  }  class Rectangle : IGeometrical, IDrawable  {     public void GetPerimeter()     {         Console.WriteLine(

interface IDrawable {    void Draw(); } interface IGeometrical {    void GetPerimeter();    void GetArea (); } class Rectangle : IGeometrical, IDrawable {    public void GetPerimeter()    {        Console.WriteLine("(a+b)*2");    }    public void GetArea()    {        Console.WriteLine("a*b");    }    public void Draw()    {        Console.WriteLine("Rectangle");    } }

 class Circle : IGeometrical, IDrawable  {      public void GetPerimeter()     {       Console.WriteLine(

class Circle : IGeometrical, IDrawable {    public void GetPerimeter()    {      Console.WriteLine("2*pi*r");    }    public void GetArea()    {      Console.WriteLine("pi*r^2");    }    public void Draw()    {      Console.WriteLine("Circle");   } }

Здесь был объявлен интерфейс  IDrawable , который предоставляет метод для рисования объекта. Этот интерфейс может реализовать, например, класс  Image .

 Классы  Image  и  Circle  совсем разные сущности, и они не имеют общего базового класса, но мы можем создать список указателей на интерфейс  IDrawable , и работать с такими объектами, как с однотипными (с одинаковым интерфейсом). Этот пример с  IDrawable  более наглядно отображает то, что нам дают интерфейсы. На практике,  IGeometrical  стоило бы заменить на абстрактный класс.

Классы  Image  и  Circle  совсем разные сущности, и они не имеют общего базового класса, но мы можем создать список указателей на интерфейс  IDrawable , и работать с такими объектами, как с однотипными (с одинаковым интерфейсом). Этот пример с  IDrawable  более наглядно отображает то, что нам дают интерфейсы. На практике,  IGeometrical  стоило бы заменить на абстрактный класс.

Операция is  При работе с объектом через объект типа интерфейса бывает необходимо убедиться, что объект поддерживает данный интерфейс.  Проверка выполняется с помощью бинарной операции is. Она определяет, совместим ли текущий тип объекта, находящегося слева от ключевого слова is, с типом, заданным справа.  Результат операции равен true, если объект можно преобразовать к заданному типу, и false в противном случае. Операция обычно используется в следующем контексте: if ( объект is тип ) {  // выполнить преобразование

Операция is

При работе с объектом через объект типа интерфейса бывает необходимо убедиться, что объект поддерживает данный интерфейс.

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

Результат операции равен true, если объект можно преобразовать к заданному типу, и false в противном случае. Операция обычно используется в следующем контексте:

if ( объект is тип )

{

// выполнить преобразование "объекта" к "типу"

// выполнить действия с преобразованным объектом

}

 Операция as  Операция as выполняет преобразование к заданному типу, а если это невозможно, формирует результат null: static void Act( object A ) {  IAction Actor = A as IAction;  if ( Actor != null ) Actor.Draw(); }  Обе рассмотренные операции применяются как к интерфейсам, так и к классам.

Операция as

Операция as выполняет преобразование к заданному типу, а если это невозможно, формирует результат null:

static void Act( object A )

{

IAction Actor = A as IAction;

if ( Actor != null ) Actor.Draw();

}

Обе рассмотренные операции применяются как к интерфейсам, так и к классам.


Скачать

Рекомендуем курсы ПК и ППК для учителей

Вебинар для учителей

Свидетельство об участии БЕСПЛАТНО!