Интерфейсы C#. Интерфейсы. Интерфейсы Введение в интерфейсы
Скачать 85.31 Kb.
|
Интерфейсы Введение в интерфейсы Интерфейс представляет ссылочный тип, который определяет набор методов и свойств, но не реализует их. Интерфейс не может содержать в себе никакого кода, который бы реализовал его члены; он просто описывает эти члены. Их реализация должна находиться в классах, в которых реализован данный интерфейс. В интерфейсе указывается только, что именно следует делать, но не как это делать. Как только интерфейс будет определен, он может быть реализован в любом количестве классов. Фактически это те же самые абстрактные классы, не содержащие объявлений данных-членов и объявлений обычных функций. Все без исключения функции — члены интерфейса – абстрактные. Определение интерфейса Для определения интерфейса используется ключевое слово interface. Как правило, названия интерфейсов в C# начинаются с заглавной буквы I, например, IComparable, IEnumerable (так называемая венгерская нотация), однако это не обязательное требование, а больше стиль программирования. Например, интерфейс IMovable: interface IMovable { void Move(); } Члены интерфейса автоматически открыты, и они не могут включать модификаторы доступа. Введение в интерфейсы Методы и свойства интерфейса могут не иметь реализации, в этом они сближаются с абстрактными методами абстрактных классов. В данном случае интерфейс определяет метод Move, который будет представлять некоторое передвижение. Он не принимает никаких параметров и ничего не возвращает. Введение в интерфейсы Еще один момент в объявлении интерфейса: все его члены - методы и свойства не имеют модификаторов доступа, но фактически по умолчанию доступ public, так как цель интерфейса - определение функционала для реализации его классом. Поэтому весь функционал должен быть открыт для реализации. Введение в интерфейсы В целом интерфейсы могут определять следующие сущности:
Затем какой-нибудь класс или структура могут применить данный интерфейс: class Person : IMovable { // применение интерфейса в классе public void Move() { } } struct Car : IMovable { // применение интерфейса в структуре public void Move() { Console.WriteLine("Машина едет"); } } Применение интерфейса в программе interface IMovable { void Move(); } class Person : IMovable { public void Move() { } } struct Car : IMovable { public void Move() { Console.WriteLine("Машина едет"); } } class Program { class Program { static void Action(IMovable movable) { movable.Move(); } Person person = new Person(); Car car = new Car(); Action(person); Action(car); } } Интерфейсы имеют еще одну важную функцию: в C# не поддерживается множественное наследование, то есть мы можем унаследовать класс только от одного класса, в отличие, скажем, от языка С++, где множественное наследование можно использовать. Интерфейсы позволяют частично обойти это ограничение, поскольку в C# класс может реализовать сразу несколько интерфейсов. Все реализуемые интерфейсы указываются через запятую: myClass: myInterface1, myInterface2, myInterface3, ... { } interface IAccount { int CurrentSum { get; } // Текущая сумма на счету void Put(int sum); // Положить деньги на счет void Withdraw(int sum); // Взять со счета } interface IClient { string Name { get; set; } } class Client : IAccount, IClient { int _sum; // Переменная для хранения суммы public string Name { get; set; } public Client(string name, int sum) { Name = name; _sum = sum; } public int CurrentSum { get { return _sum; } } public void Put(int sum) { _sum += sum; } public void Withdraw(int sum) { if (_sum >= sum) {_sum -= sum;} } } class Program { Client client = new Client("Tom", 200); client.Put(30); Console.WriteLine(client.CurrentSum); //230 client.Withdraw(100); Console.WriteLine(client.CurrentSum); //130 Console.Read(); } } Создание интерфейса Стоит отметить, что в Visual Studio есть специальный компонент для добавления нового интерфейса в отдельном файле. Для добавления интерфейса в проект можно нажать правой кнопкой мыши на проект и в появившемся контекстном меню выбрать Add->New Item... и в диалоговом окне добавления нового компонента выбрать пункт Interface: Создание интерфейса Если класс применяет интерфейс, то этот класс должен реализовать все методы и свойства интерфейса. Однако также можно и не реализовать методы, сделав их абстрактными, переложив право их реализации на производные классы: interface IMovable { void Move(); } abstract class Person : IMovable { public abstract void Move(); } class Driver : Person { public override void Move() { Console.WriteLine("Шофер ведет машину"); } } При реализации интерфейса учитываются также методы и свойства, унаследованные от базового класса. Например: interface IAction { void Move(); } class BaseAction { public void Move() { Console.WriteLine("Move in BaseAction"); } } class HeroAction : BaseAction, IAction { } Начиная с версии C# 8.0 интерфейсы поддерживают реализацию методов и свойств по умолчанию. Это значит, что мы можем определить в интерфейсах полноценные методы и свойства, которые имеют реализацию как в обычных классах. Зачем это нужно? Допустим, у нас есть куча классов, которые реализуют некоторый интерфейс. Если мы добавим в этот интерфейс новый метод, то мы будем обязаны реализовать этот метод во всех классах, применяющих данный интерфейс. Иначе подобные классы просто не будут компилироваться. Теперь вместо реализации метода во всех классах нам достаточно определить его реализацию по умолчанию в интерфейсе. Если класс не реализует метод, будет применяться реализация по умолчанию. class Program { IMovable tom = new Person(); Car tesla = new Car(); tom.Move(); // Идет tesla.Move(); // Едет } } interface IMovable { void Move() { Console.WriteLine(“Идет"); } } class Person : IMovable { } class Car : IMovable { public void Move() { Console.WriteLine("Едет"); } } Для примера из лаб. 11_1 abstract class Animal { public string Name; protected int Weight; private int Type; public int Animal(int W, int T, string N) { Weight=W; Type=T; Name=N; } public int GetWeight() { return Weight; } } Продолжение сл 19 interface ISpecies { string Species(); void Feed(); } class Cheetah:Animal,ISpecies{ private string ScientificName; public string Species() { return ScientificName; } public void Feed () { Weight++; } } |