Шаг 159.
Язык программирования C#. Начала.
Абстрактные классы и интерфейсы. Наследование интерфейсов

    На этом шаге мы рассмотрим особенности реализации такого наследования.

    Один интерфейс может наследовать другой интерфейс или даже несколько интерфейсов. Технически наследование интерфейсов реализуется так: в описании интерфейса, наследующего другие интерфейсы, после его имени через двоеточие указываются наследуемые интерфейсы. Общий шаблон наследования интерфейсов выглядит следующим образом:

  interface имя: интерфейс1, интерфейс2, ..., интерфейсN {
    // Тело интерфейса
  }

    Если интерфейс Alpha наследует интерфейс Bravo, то все, что объявлено в интерфейсе Bravo, автоматически включается в состав интерфейса Alpha. Поэтому если некоторый класс MyClass реализует интерфейс Alpha, который наследует интерфейс Bravo, то фактически в этом классе должно быть описано все, что явно объявлено в интерфейсе Alpha, и все, что описано в интерфейсе Bravo (поскольку содержимое интерфейса Bravo по факту содержится и в интерфейсе Alpha).


Нередко вместо термина "наследование интерфейсов" для обозначения ситуации, когда интерфейс создается на основе одного или более уже существующих интерфейсов, используют термин "расширение интерфейсов".

    Программа, в которой используется наследование интерфейсов, представлена ниже. Это еще одна вариация на тему примеров из последних двух шагов (для сокращения объема программного кода некоторые комментарии удалены).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr159_1
{
    // Первый интерфейс: 
    interface First {
        // Свойство: 
        int number { 
            get; 
            set;
        }
        // Индексатор: 
        int this[int k]{ 
            get;
        }
    }

    // Второй интерфейс: 
    interface Second {
        // Методы:
        void setNum(int n);
        int getNum();
    }

    // Интерфейс наследует другие интерфейсы: 
    interface MyInterface: First, Second {
        // Метод: 
        void show();
    }

    // Класс реализует интерфейс: 
    class MyClass: MyInterface { 
        private int num; 
        public MyClass(int n) { 
            number = n; 
            show();
        }
        public void show() {
            Console.WriteLine("Свойство number = " + number);
        }
        public void setNum(int n) { 
            num = n;
        }
        public int getNum() { 
            return num;
        }
        public int number{ 
            get {
                return getNum();
            }
            set {
                setNum(value);
            }
        }
        public int this[int k]{ 
            get {
                int r = number; 
                for(int i = 0; i < k; i++) { 
                    r /= 10;
                }
                return r % 10;
            }
        }
    }

    // Класс с главным методом: 
    class Program
    {
        static void Main()
        {
            int m = 9;
            MyClass obj = new MyClass(12345); 
            for (int i = 0; i <= m; i++)
            {
                Console.Write("|" + obj[m - i]);
            }
            Console.WriteLine("|");
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы такой же, как и в предыдущих случаях:


Рис.1. Результат выполнения программы

    Описание класса MyClass не изменилось (как и команды в главном методе). Класс MyClass реализует интерфейс MyInterface. Но только теперь сам интерфейс MyInterface наследует интерфейсы First и Second. В интерфейсе First объявлено свойство number и индексатор. В интерфейсе Second объявлены методы setNum() и getNum(). Непосредственно в интерфейсе MyInterface объявлен метод show(). Но поскольку интерфейс MyInterface наследует интерфейсы First и Second, то содержимое этих интерфейсов "незримо присутствует" в интерфейсе MyInterface. Поэтому класс, реализующий интерфейс MyInterface, должен содержать описание не только тех методов, свойств и индексаторов, которые объявлены непосредственно в интерфейсе MyInterface, но и описание всего, что объявлено в интерфейсах, наследуемых в интерфейсе MyInterface.

    На следующем шаге мы рассмотрим интерфейсные переменные.




Предыдущий шаг Содержание Следующий шаг