Практическое работа № 12
Тема: Интерфейсы. Полиморфизм на основе интерфейсов
Цель работы: освоить технику реализации интерфейсов классами и использования интерфейсов для достижения полиморфизма.
Краткие теоретические сведения
Интерфейс представляет ссылочный тип, который может определять некоторый функционал - набор методов и свойств без реализации. Затем этот функционал реализуют классы и структуры, которые применяют данные интерфейсы.
Определение интерфейса
Для определения интерфейса используется ключевое слово interface. Как правило, названия интерфейсов в C# начинаются с заглавной буквы I, например, IComparable, IEnumerable.
Упрощенная форма объявления интерфейса:
interface имя{
возвращаемый_тип имя_метода_1 (список_параметров);
возвращаемый_тип имя_метода_2 (список_параметров);
// ...
возвращаемый_тип имя_метода_N (список_параметров);
}
где имя — это конкретное имя интерфейса. В объявлении методов интерфейса используются только их возвращаемый_тип и сигнатура. Они, по существу, являются абстрактными методами. Как пояснялось выше, в интерфейсе не может быть никакой реализации. Поэтому все методы интерфейса должны быть реализованы в каждом классе, включающем в себя этот интерфейс. В самом же интерфейсе методы неявно считаются открытыми, поэтому доступ к ним не нужно указывать явно.
Помимо методов, в интерфейсах можно также указывать свойства, индексаторы и события. Интерфейсы не могут содержать члены данных. В них нельзя также определить конструкторы, деструкторы или операторные методы. Кроме того, ни один из членов интерфейса не может быть объявлен как static.
Как только интерфейс будет определен, он может быть реализован в одном или нескольких классах. Для реализации интерфейса достаточно указать его имя после имени класса, аналогично базовому классу. Ниже приведена общая форма реализации интерфейса в классе:
class имя_класса : имя_интерфейса {
// тело класса
}
где имя_интерфейса — это конкретное имя реализуемого интерфейса. Если уж интерфейс реализуется в классе, то это должно быть сделано полностью. В частности, реализовать интерфейс выборочно и только по частям нельзя.
В классе допускается реализовывать несколько интерфейсов. В этом случае все
реализуемые в классе интерфейсы указываются списком через запятую. В классе можно наследовать базовый класс и в тоже время реализовать один или более интерфейс. В таком
случае имя базового класса должно быть указано перед списком интерфейсов, разделяемых запятой.
Методы, реализующие интерфейс, должны быть объявлены как public. Дело в том, что в самом интерфейсе эти методы неявно подразумеваются как открытые, поэтому их реализация
также должна быть открытой. Кроме того, возвращаемый тип и сигнатура реализуемого метода должны точно соответствовать возвращаемому типу и сигнатуре, указанным в определении интерфейса.
Интерфейсы могут определять следующие сущности:
Интерфейсы не могут определять нестатические переменные.
Например, простейший интерфейс, который определяет все эти компоненты:
interface IMovable
{
// константа
const int minSpeed = 0; // м
н
ма
ьная скорость
// стат
ческая переменная
static int maxSpeed = 60; // макс
ма
ьная скорость
// метод
void Move(); // дв
жен
е
// свойство
string
ame { get; set; } // назван
е
delegate void Move
andler(string message); // опреде
ен
е де
егата д
я соб
т
я
// соб
т
е
event Move
andler MoveEvent; // соб
т
е дв
жен
я
}
Пример
using System;
using System.Collections.Generic; using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
// Создаем два
нтерфейса, оп
с
вающ
х абстрактн
е метод
// ар
фмет
ческ
х операц
й
операц
й Sqrt
Sqr public interface IArOperation
{
// Опреде
яем набор абстрактн
х методов int Sum();
int Otr(); int flrz(); int Del();
}
public interface ISqrSqrt
{
int Sqr(int x); int Sqrt(int x);
}
// Данн
й к
асс реа
зует
нтерфейс IArOperation class A : IArOperation
{
int My_x, My_y;
public int x
{
set { My_x = value; } get { return My_x; }
}
public int y
{
set { My_y = value; } get { return My_y; }
}
public A() { }
public A(int x, int y)
{
this.x = x; this.y = y;
}
// Реа
зуем метод
нтерфейса public virtual int Sum()
{
return x + y;
}
public int Otr()
{
return x - y;
}
public int flrz()
{
return x * y;
}
public int Del()
{
return x / y;
}
// В данном к
ассе так же можно реа
зовать собственн
е метод
public virtual void rewrite()
{
Console.WriteLine("Переменная x: {0}\nПеременная y: {1}", x, y);
}
}
// Данн
й к
асс унас
едован от к
асса А, но пр
этом в нем не нужно
// заново реа
зов
вать
нтерфейс, но пр
этом можно переопреде
ть
// некотор
е его метод
class Aa : A
{
public int z;
public Aa(int z, int x, int y)
: base(x, y)
{
this.z = z;
}
// Переопреде
м метод Sum public override int Sum()
{
return base.x + base.y + z;
}
public override void rewrite()
{
base.rewrite(); Console.WriteLine("Переменная z: " + z);
}
}
// Данн
й к
асс унас
едован от к
асса А,
пр
этом
// реа
зует
нтерфейс ISqrSqrt class Ab : A, ISqrSqrt
{
public int Sqr(int x)
{
return x * x;
}
public int Sqrt(int x)
{
return (int)Math.Sqrt((double)(x));
}
}
class flrogram
{
static void Main()
{
A obj1 = new A(x: 10, y: 12); Console.WriteLine("obj1: "); obj1.rewrite();
Console.WriteLine("{0} + {1} = {2}", obj1.x, obj1.y, obj1.Sum());
Console.WriteLine("{0} * {1} = {2}", obj1.x, obj1.y, obj1.flrz()); Aa obj2 = new Aa(z: -3, x: 10, y: 14); Console.WriteLine("\nobj2: ");
obj2.rewrite();
Console.WriteLine("{0} + {1} + {3} = {2}", obj2.x, obj2.y, obj2.Sum(), obj2.z);
Console.ReadLine();
}
}
}

Результат:
Обратите внимание на структуру реализации данных интерфейсов в приведенном примере. Диаграмма классов, иллюстрирующая вышеуказанный пример показана ниже:
Добавление интерфейса
Стоит отметить, что в Visual Studio есть специальный компонент для добавления нового интерфейса в отдельном файле. Для добавления интерфейса в проект можно нажать правой
кнопкой мыши на проект и в появившемся контекстном меню выбрать Add- New Item... и в диалоговом окне добавления нового компонента выбрать пункт Interface:
Задание:
Составить список студентов группы, включив следующие данные: ФИО, номер группы, результаты сдачи трех экзаменов. Вывести в новый список информацию о студентах, успешно сдавших сессию, отсортировав по номеру группы.
Контрольные вопросы:
Что такое полиморфизм
Как объявить интерфейс в C#?