Реализация интерфейсов C#, Интерфейс в C#, ISeries в C#, C# Полное руководство Герберт Шилдт, Язык программирования C#, C# полное руководство
Как только интерфейс будет определен, он может быть реализован в одном или более классе. Для реализации интерфейса достаточно указать его имя после имени класса, аналогично базовому классу. Ниже приведена общая форма реализации интерфейса в классе.
class имя_класса : имя_интерфейса { // тело класса }
где имя_интерфейса — это конкретное имя реализуемого интерфейса. Если уж интерфейс реализуется в классе, то это должно быть сделано полностью. В частности, реализовать интерфейс выборочно и только по частям нельзя. В классе допускается реализовать несколько интерфейсов. В этом случае все реализуемые в классе интерфейсы указываются списком через запятую. В классе можно наследовать базовый класс и в тоже время реализовать один или более интерфейс. В таком случае имя базового класса должно быть указано перед списком интерфейсов, разделяемых запятой. Методы, реализующие интерфейс, должны быть объявлены как public. Дело в том, что в самом интерфейсе эти методы неявно подразумеваются как открытые, поэтому их реализация также должна быть открытой. Кроме того, возвращаемый тип и сигнатура реализуемого метода должны точно соответствовать возвращаемому типу и сигнатуре, указанным в определении интерфейса. Ниже приведен пример программы, в которой реализуется представленный ранее интерфейс ISeries. В этой программе создается класс ByTwos, генерирующий последовательный ряд чисел, в котором каждое последующее число на два больше предыдущего.
// Реализовать интерфейс ISeries. class ByTwos : ISeries { int start; int val;
public ByTwos () { start = 0; val =0; }
public int GetNext() { val += 2; return val; }.
public void Reset() { val = start; }
public void SetStart(int x) { start = x; val = start; } }
Как видите, в классе ByTwos реализуются три метода, определяемых в интерфейсе ISeries. Как пояснялось выше, это приходится делать потому, что в классе нельзя реализовать интерфейс частично. Ниже приведен код класса, в котором демонстрируется применение класса ByTwos, реализующего интерфейс ISeries.
// Продемонстрировать применение класса ByTwos, // реализующего интерфейс.
using System;
class SeriesDemo { static void Main() { ByTwos ob = new ByTwos () ;
for(int i=0; i < 5; i++) Console.WriteLine("Следующее число равно " + ob.GetNext());
Console.WriteLine("\nСбросить"); ob.Reset () ; for(int i=0; i < 5; i++) Console.WriteLine("Следующее число равно " + ob.GetNext()); Console.WriteLine("\nНачать с числа 100"); ob.SetStart(100); for(int i=0; i < 5; i++) Console.WriteLine("Следующее число равно " + ob.GetNext()); } }
Для того чтобы скомпилировать код класса SeriesDemo, необходимо включить в компиляцию файлы, содержащие интерфейс ISeries, а также классы ByTwos и SeriesDemo. Компилятор автоматически скомпилирует все три файла и сформирует из них окончательный исполняемый файл. Так, если эти файлы называются ISeries.cs, ByTwos.cs и SeriesDemo. cs, то программа будет скомпилирована в следующей командной строке:
>csc SeriesDemo.cs ISeries.cs ByTwos.cs
В интегрированной срёде разработки Visual Studio для этой цели достаточно ввести все три упомянутых выше файла в конкретный проект С#. Кроме того, все три компилируемых элемента (интерфейс и оба класса) допускается включать в единый файл. Ниже приведен результат выполнения скомпилированного кода. Следующее число равно 2 Следующее число равно 4 Следующее число равно 6 Следующее число равно 8 Следующее число равно 10
Сбросить. Следующее число равно 2 Следующее число равно 4 Следующее число равно 6 Следующее число равно 8 Следующее число равно 10 Начать с числа 100. Следующее число равно 102 Следующее число равно 104 Следующее число равно 106 Следующее число равно 108 Следующее число равно 110 В классах, реализующих интерфейсы, разрешается и часто практикуется определять их собственные дополнительные члены. В качестве примера ниже приведен другой вариант класса ByTwos, в который добавлен метод GetPrevious (), возвращающий предыдущее значение.
// Реализовать интерфейс ISeries и добавить в // класс ByTwos метод GetPrevious() .
class ByTwos : ISeries { int start; int val; int prev;
public ByTwos() { start = 0; val = 0; prev = -2; }
public int GetNext () { prev = val; , val += 2; return val; }
public void Reset () { val = start; prev = start - 2; }
public void SetStart(int x) { start = x; val = start; prev = val - 2; }
// Метод, не указанный в интерфейсе ISeries. public int GetPrevious () { return prev; } }
Как видите, для того чтобы добавить метод GetPrevious (), потребовалось внести изменения в реализацию методов, определяемых в интерфейсе ISeries. Но поскольку интерфейс для этих методов остается прежним, то такие изменения не вызывают никаких осложнений и не нарушают уже существующий код. В этом и заключается одно из преимуществ интерфейсов. Как пояснялось выше, интерфейс может быть реализован в любом количестве классов. В качестве примера ниже приведен класс Primes, генерирующий ряд простых чисел. Обратите внимание на то, реализация интерфейса ISeries в этом классе коренным образом отличается от той, что предоставляется в классе ByTwos.
// Использовать интерфейс ISeries для реализации // процесса генерирования простых чисел.
class Primes : ISeries { int start; int val;
public Primes() { start = 2; val = 2; }
public int GetNext () { int i, j; bool isprime;
val++; for(i = val; i < 1000000; i++) { isprime = true; for (j = 2; j <= i / j; j++) { if ( (i % j ) == 0) { isprime = false; break; } } if(isprime) { val = i; break; } } return val; }
public void Reset () { val = start; }
public void SetStart(int x) { start = x; val = start; } }
Самое любопытное, что в обоих классах, ByTwos и Primes, реализуется один и тот же интерфейс, несмотря на то, что в них генерируются совершенно разные ряды чисел. Как пояснялось выше, в интерфейсе вообще отсутствует какая-либо реализация, поэтому он может быть свободно реализован в каждом классе так, как это требуется для самого класса.
|