Для того чтобы скомпилировать код класса 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
, реализуется один и тот же интерфейс, несмотря на то, что в них генерируются совершенно разные ряды чисел. Как пояснялось выше, в интерфейсе вообще отсутствует какая-либо реализация, поэтому он может быть свободно реализован в каждом классе так, как это требуется для самого класса.
Применение интерфейсных ссылок