Лабораторная работа №11
Разработка интерфейсов, исследование механизма наследования интерфейсов и
Применение их в программах
Цель работы:
Научиться разрабатывать программы, которые реализуют механизм наследования интерфейсов с использованием среды Visual Studio.Net.
Теоретические сведения
Интерфейсы – это еще один инструмент реализации полиморфизма в Си-шарп. Интерфейс представляет собой набор методов (свойств, событий, индексаторов), реализацию которых должен обеспечить класс, который реализует интерфейс.
Интерфейс может содержать только сигнатуры (имя и типы параметров) своих членов. Интерфейс не может содержать конструкторы, поля, константы, статические члены. Создавать объекты интерфейса невозможно.
Объявление интерфейса
Интерфейс – это единица уровня класса, он объявляется за пределами класса, при помощи ключевого слова interface:
interface ISomeInterface
{
// тело интерфейса
}
* Имена интерфейсам принято давать, начиная с префикса «I», чтобы сразу отличать где класс, а где интерфейс.
Внутри интерфейса объявляются сигнатуры его членов, модификаторы доступа указывать не нужно:
interface ISomeInterface
{
string SomeProperty { get; set; } // свойство
void SomeMethod(int a); // метод
}
Реализация интерфейса
Чтобы указать, что класс реализовывает интерфейс, необходимо, так же, как и при наследовании, после имени класса и двоеточия указать имя интерфейса:
class SomeClass: ISomeInterface // реализация интерфейса ISomeInterface
{
// тело класса
}
Класс, который реализовывает интерфейс, должен предоставить реализацию всех членов интерфейса:
class SomeClass: ISomeInterface
{
public string SomeProperty
{
Get
{
// тело get аксессора
}
Set
{
// тело set аксессора
}
}
public void SomeMethod(int a)
{
// тело метода
}
}
Пример
Есть классы геометрических фигур Прямоугольник и Окружность. У обоих классов должны быть методы вычисления периметра и площади. Эти методы мы представим интерфейсом:
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("2*pi*r");
}
public void GetArea()
{
Console.WriteLine("pi*r^2");
}
}
class Program
{
static void Main(string[] args)
{
List<IGeometrical> figures = new List<IGeometrical>();
figures.Add(new Rectangle());
figures.Add(new Circle());
foreach (IGeometrical f in figures)
{
f.GetPerimeter();
f.GetArea();
}
Console.ReadLine();
}
}
В итоге, мы все так же можем объединить в один список объекты классов, которые реализуют один и тот же интерфейс.
Очень похоже на абстрактные классы
Первый вопрос, который обычно приходит в голову тем, кто изучает интерфейсы – Зачем вообще интерфейсы? Это так похоже на абстрактные классы.
Чтобы ответить на этот вопрос, для начала необходимо разобраться с такой вещью, как множественное наследование.
Множественное наследование – это когда один класс сразу наследуется от нескольких классов. Но бывает так, что базовые классы содержат методы с одинаковыми именами, в результате чего возникают определенные неточности и ошибки. Множественное наследование есть в языке C++, а в C# от него отказались и внесли интерфейсы. В C# класс может реализовывать сразу несколько интерфейсов. Это и является главным отличием использования интерфейсов и абстрактных классов. Кроме того, конечно же, абстрактные классы могут содержать все остальные члены, которых не может быть в интерфейсе, и не все методы/свойства в абстрактном классе должны быть абстрактными.
Если класс реализовывает несколько интерфейсов, они разделяются запятыми:
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("2*pi*r");
}
public void GetArea()
{
Console.WriteLine("pi*r^2");
}
public void Draw()
{
Console.WriteLine("Circle");
}
}
Здесь был объявлен интерфейс IDrawable, который предоставляет метод для рисования объекта. Этот интерфейс может реализовывать, например, класс Image. Классы Image и Circle совсем разные сущности, и они не имеют общего базового класса, но мы можем создать список указателей на интерфейс IDrawable, и работать с такими объектами, как с однотипными (с одинаковым интерфейсом). Этот пример с IDrawable более наглядно отображает то, что нам дают интерфейсы. На практике, IGeometrical стоило бы заменить на абстрактный класс.
Контрольные вопросы
1. Как такое интерфейс?
2. Как его объявить?
3. Как его реализовать?
Задание
Создайте интерфейс ISwitchable, в котором объявите два метода – включение и выключение. Придумайте и создайте два класса, которые будут реализовывать этот интерфейс.