Похожие презентации:
Алгоритмизация и программирование
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. Интерфейсы
78. Интерфейсы
Наследование интерфейсовОдин интерфейс может наследовать другой. Синтаксис наследования
интерфейсов такой же, как и у классов. Когда в классе реализуется
один интерфейс, наследующий другой, в нем должны быть
реализованы все члены, определенные в цепочке наследования
интерфейсов, как в примере.
ПРИМЕР.
// Пример наследования интерфейсов.
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
Программирование