АЛГОРИТМИЗАЦИЯ И ПРОГРАММИРОВАНИЕ
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
Интерфейсы
426.00K
Category: programmingprogramming

Алгоритмизация и программирование

1. АЛГОРИТМИЗАЦИЯ И ПРОГРАММИРОВАНИЕ

2. Интерфейсы

Интерфейсные индексаторы
В интерфейсе можно также указывать индексаторы. Общая форма
объявления интерфейсного индексатора.
// Интерфейсный индексатор
тип_элемента this[int индекс]{
get;
set;
}
В объявлении интерфейсных индексаторов, доступных только для
чтения или только для записи, должен присутствовать единственный
аксессор: get или set соответственно.
2

3. Интерфейсы

ПРИМЕР
Вариант реализации интерфейса ISeries, в котором добавлен
индексатор только для чтения, возвращающий i-й элемент числового
ряда.
// Добавить индексатор в интерфейс.
using System;
public interface ISeries {
// Интерфейсное свойство.
int Next {
get; // возвратить следующее по порядку число
set; // установить следующее число
}
// Интерфейсный индексатор.
int this[int index] {
get; // возвратить указанное в ряду число
}
}
3

4. Интерфейсы

ПРИМЕР
// Реализовать интерфейс ISeries.
class ByTwos : ISeries {
int val;
public ByTwos() {
val = 0;
}
// Получить или установить значение с помощью свойства.
public int Next {
get {
val += 2;
return val;
}
set {
val = value;
}
}
4

5. Интерфейсы

ПРИМЕР
// Получить значение по индексу.
public int this[int index] {
get {
val = 0;
for(int i=0; i < index; i++)
val += 2;
return val;
}
}
}
5

6. Интерфейсы

ПРИМЕР
// Применение интерфейсного индексатора.
class SeriesDemo {
static void Main() {
ByTwos ob = new ByTwos();
//Получить доступ к последовательному ряду чисел с помощью
свойства.
for(int i=0; i < 5; i++)
Console.WriteLine("Следующее число равно " + ob.Next);
Console.WriteLine("\nНачать с числа 21");
ob.Next = 21;
for (int i=0; i < 5; i++)
Console.WriteLine("Следующее число равно " + ob.Next);
Console.WriteLine("\nСбросить в 0");
ob.Next = 0;
//Получить доступ к последовательному ряду чисел с помощью
индексатора
for(int i=0; i < 5; i++)
6
Console.WriteLine("Следующее число равно " + ob[i]); } }

7. Интерфейсы

7

8. Интерфейсы

Наследование интерфейсов
Один интерфейс может наследовать другой. Синтаксис наследования
интерфейсов такой же, как и у классов. Когда в классе реализуется
один интерфейс, наследующий другой, в нем должны быть
реализованы все члены, определенные в цепочке наследования
интерфейсов, как в примере.
ПРИМЕР.
// Пример наследования интерфейсов.
using System;
public interface IA {
void Meth1();
void Meth2();
}
// В базовый интерфейс включены методы Meth1() и Meth2().
// а в производный интерфейс добавлен еще один метод — Meth3().
public interface IB : IA {
void Meth3();
}
8

9. Интерфейсы

Наследование интерфейсов
ПРИМЕР.
// В этом классе должны быть реализованы все методы интерфейсов IA
и IB.
class MyClass : IB {
public void Meth1() {
Console.WriteLine("Реализовать метод Meth1().");
}
public void Meth2() {
Console.WriteLine("Реализовать метод Meth2().");
}
public void Meth3() {
Console.WriteLine("Реализовать метод Meth3().");
}
}
9

10. Интерфейсы

Наследование интерфейсов
ПРИМЕР.
class IFExtend {
static void Main() {
MyClass ob = new MyClass();
ob.Meth1();
ob.Meth2();
ob.Meth3();
}
}
10

11. Интерфейсы

При реализации члена интерфейса имеется возможность указать его
имя полностью вместе с именем самого интерфейса. В этом случае
получается явная реализация члена интерфейса, или просто явная
реализация.
Так, если объявлен интерфейс IMyIF
interface IMyIF {
int MyMeth(int x);
}
то следующая его реализация считается вполне допустимой:
class MyClass : IMyIF {
int IMyIF.MyMeth(int x) {
return x / 3;
}
}
При реализации члена MyMeth() интерфейса IMyIF указывается его
полное имя, включающее в себя имя его интерфейса.
11

12. Интерфейсы

Для явной реализации интерфейсного метода могут быть две причины.
Во-первых, когда интерфейсный метод реализуется с указанием его
полного имени, то такой метод оказывается доступным не
посредством объектов класса, реализующего данный интерфейс, а
по интерфейсной ссылке. Следовательно, явная реализация
позволяет реализовать интерфейсный метод таким образом, чтобы
он не стал открытым членом класса, предоставляющего его
реализацию.
Во-вторых, в одном классе могут быть реализованы два интерфейса с
методами, объявленными с одинаковыми именами и сигнатурами. Но
неоднозначность в данном случае устраняется благодаря указанию в
именах этих методов их соответствующих интерфейсов. Рассмотрим
каждую из этих двух возможностей явной реализации на конкретных
примерах.
12

13. Интерфейсы

ПРИМЕР.
В приведенном примере программы демонстрируется интерфейс IEven,
в котором объявляются два метода: IsEven() и IsOdd(). В первом из
них определяется четность числа, а во втором - его нечетность.
Интерфейс IEven затем реализуется в классе MyClass. При этом
метод IsOdd() реализуется явно.
// Реализовать член интерфейса явно.
using System;
interface IEven {
bool IsOdd(int x);
bool IsEven(int x);
}
13

14. Интерфейсы

ПРИМЕР.
class MyClass : IEven {
// Явная реализация. Этот член является закрытым по умолчанию.
bool IEven.IsOdd(int x) {
if((x%2) != 0) return true;
else return false;
}
// Обычная реализация,
public bool IsEven(int x) {
IEven о = this; // Интерфейсная ссылка на вызывающий объект.
return !о.IsOdd(x);
}
}
14

15. Интерфейсы

ПРИМЕР.
class Demo {
static void Main() {
MyClass ob = new MyClass();
bool result;
result = ob.IsEven(4);
if(result) Console.WriteLine("4 - четное число.");
//result = ob.IsOdd(4); // Ошибка, член IsOdd интерфейса IEven
недоступен
// Следующий код написан верно, поскольку в нем сначала
создается
// интерфейсная ссылка типа IEven на объект класса MyClass, а
затем по
// этой ссылке вызывается метод IsOdd().
IEven iRef = (IEven) ob;
result = iRef.IsOdd(3);
if(result) Console.WriteLine("3 - нечетное число.");
}
15
}

16. Интерфейсы

ПРИМЕР.
В примере метод IsOdd() реализуется явно, а значит, он недоступен как
открытый член класса MyClass.
Метод IEven.IsOdd доступен только по интерфейсной ссылке. Именно
поэтому вызывается посредством переменной ссылочного типа IEven
в реализации метода IsEven().
16

17. Интерфейсы

ПРИМЕР.
Пример программы, в которой реализуются два интерфейса, в обоих
интерфейсах объявляется метод Meth(). Благодаря явной
реализации исключается неоднозначность, характерная для
подобной ситуации.
// Воспользоваться явной реализацией для устранения
неоднозначности.
using System;
interface IMyIF_A {
int Meth(int x);
}
interface IMyIF_B {
int Meth(int x);
}
// Оба интерфейса реализуются в классе MyClass.
class MyClass : IMyIF_A, IMyIF_B {
// Реализовать оба метода Meth() явно.
int IMyIF_A.Meth(int x) {
17
return x + x;
}

18. Интерфейсы

ПРИМЕР.
int IMyIF_B.Meth(int x) {
return x * x;
}
// Вызывать метод Meth() по интерфейсной ссылке.
public int MethA(int x) {
IMyIF_A a_ob;
a_ob = this;
return a_ob.Meth(x); // вызов интерфейсного метода IMyIF_A
}
public int MethB(int x){
IMyIF_B b_ob;
b_ob = this;
return b_ob.Meth(x); // вызов интерфейсного метода IMyIF_B
}
}
18

19. Интерфейсы

ПРИМЕР.
class FQIFNames {
static void Main() {
MyClass ob = new MyClass();
Console.Write("Вызов метода IMyIF_A.Meth(): ");
Console.WriteLine(ob.MethA(3));
Console.Write("Вызов метода IMyIF_B.Meth(): ");
Console.WriteLine(ob.MethB(3));
}
}
19

20. Интерфейсы

ПРИМЕР.
Одинаковая сигнатуру метода Meth() в обоих интерфейсах, IMyIF_A и
IMyIF_B.
Когда оба этих интерфейса реализуются в классе MyClass, для каждого
из них в отдельности это делается явно, т.е. с указанием полного
имени метода Meth(). А поскольку явно реализованный метод может
вызываться только по интерфейсной ссылке, то в классе MyClass
создаются две такие ссылки: одна - для интерфейса IMyIF_A, а
другая - для интерфейса IMyIF_B.
Именно по этим ссылкам происходит обращение к объектам данного
класса с целью вызвать методы соответствующих интерфейсов,
благодаря чему и устраняется неоднозначность.
20

21. Интерфейсы

ПРИМЕР
В отличие от классов допускается создание одного интерфейса из
многих (множественное наследование).
using System;
namespace a_interface
{
public interface IPrice
{
double Price();
}
public interface ICar
{
int Speed {get; set;}
void GetInfo();
}
21

22. Интерфейсы

ПРИМЕР
public class Ferrari : ICar,IPrice
{
private int spd; // скорость (поле)
public int Speed // скорость (свойство)
{
get { return spd; }
set { spd = value; }
}
// Конкретная реализация интерфейса в классе:
public void GetInfo()
{
Speed=250;
Console.WriteLine("Это суперкар Ferrari с макс. скоростью {0}", Speed);
}
// Конкретная реализация интерфейса в классе:
public double Price()
{
22
Console.WriteLine("Цена автомобиля - МНОГО");
return 0;}}

23. Интерфейсы

ПРИМЕР
class Program
{
public static void Main()
{
Console.WriteLine("Подключение к классу более одного интерфейса");
Ferrari fr = new Ferrari();
fr.GetInfo();
}
}
}
23

24. Интерфейсы

В программе объявлен интерфейс ICar с одним свойством Speed
(скорость автомобиля) и одним методом GetInfo(). Что делает этот
метод, определяется в классе, который станет подключать данный
метод.
Создан класс Ferrari (марка автомобиля), и в классе определены поле
spd (скорость) и к нему свойство Speed. В класс добавлена
конкретная реализация абстрактного метода интерфейса ICar:
установлена максимальная скорость автомобиля и выдана об этом
информация.
24

25. Интерфейсы

ПРИМЕР
Подключается возврат стоимости автомобиля
using System;
namespace a_interface
{
public interface IPrice
{
double Price();
}
public interface ICar
{
int Speed {get; set;}
void GetInfo();
}
25

26. Интерфейсы

ПРИМЕР
public class Ferrari : ICar,IPrice
{
private int spd; // скорость (поле)
public int Speed // скорость (свойство)
{
get { return spd; }
set { spd = value; }
}
// Конкретная реализация интерфейса в классе:
public void GetInfo()
{
Speed=250;
Console.WriteLine("Это суперкар Ferrari с макс. скоростью {0}", Speed);
}
// Конкретная реализация интерфейса в классе:
public double Price()
{
26
return 20000;
}

27. Интерфейсы

ПРИМЕР
class Program
{
public static void Main()
{
Console.WriteLine("Подключение к классу более одного интерфейса");
Ferrari fr = new Ferrari();
fr.GetInfo();
Console.WriteLine("Цена автомобиля — {0}",fr.Price());
}}}}
27

28. Интерфейсы

ПРИМЕР
using System;
namespace a_interface
{
public interface IM
{
string Name { get; set; }
void Move();
}
public class Person : IM
{
public string Name { get; set; }
public void Move()
{
Console.WriteLine("Человек движется...");
}
}
28

29. Интерфейсы

ПРИМЕР
public class Animal : IM
{
public string Name { get; set; }
public void Move()
{
Console.WriteLine("Животное движется...");
}
}
29

30. Интерфейсы

ПРИМЕР
class Program
{
static void GoToPoint(IM moveable)
{
Console.WriteLine($"{moveable.Name} движется до точки...");
}
public static void Main()
{
IM p = new Animal();
p.Name = "Зебра";
p.Move();
GoToPoint(p);
IM p1 = new Person();
p1.Name = "Иван";
p1.Move();
GoToPoint(p1);
}}}
Person p1 = new Person();
p1.Name = "Иван";
p1.Move();
GoToPoint(p1);
30

31. Интерфейсы

В
C# возможно с помощью ключевого слова as
поддерживает ли данный тип тот или иной интерфейс.
определить,
Допустим
необходимо
проверить,
действительно
ли
объект p поддерживает (реализует) какой-либо интерфейс. Для этого
используется ключевое слово as:
IM imovable = p as IM;
Можно провести проверку на null и если все хорошо, то можем
проводить какие-то действия:
if (p != null)
{
Console.WriteLine (“Все хорошо, можно что-то делать” );
}
else
{
Console.WriteLine (“Объект null и не реализует данный интерфейс” );
31
}

32. Интерфейсы

Проверить, был ли реализован нужный интерфейс, можно также с
помощью ключевого слова is.
Если запрашиваемый объект не совместим с указанным интерфейсом,
возвращается значение false, а если совместим, то можно выполнять
какие-либо действия.
if (p is IM)
{
Console.WriteLine (“Все хорошо, можно что-то делать” );
}
else
{
Console.WriteLine (“Объект не реализует данный интерфейс” );
}
32
English     Русский Rules