TOC

This article has been localized into Russian by the community.

Классы:

Интерфейсы

В предыдущих главах мы рассматривали абстрактные классы. Интерфейсы очень похожи на них, и они разделяют тот факт, что их экземпляры не могут быть созданы. Однако интерфейсы являются даже более концептуальными, чем абстрактные классы, поскольку тела методов не допускаются вообще. Таким образом, интерфейс подобен абстрактному классу, в котором нет ничего, кроме абстрактных методов, и поскольку нет методов с фактическим кодом, нет необходимости в каких-либо полях. Однако свойства, а также индексаторы и события, разрешены. Интерфейс можно рассматривать как контракт - класс, реализующий все необходимые методы и свойства. Однако самое главное отличие заключается в том, что хотя C# не допускает множественного наследования, где классы наследуют более одного базового класса, он фактически позволяет реализовать несколько интерфейсов!

Итак, как все это выглядит в коде? Вот довольно полный пример. Посмотрите, возможно, попробуйте сами, а затем прочитайте полное объяснение:

using System;
using System.Collections.Generic;

namespace Interfaces
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Dog> dogs = new List<Dog>();
            dogs.Add(new Dog("Fido"));
            dogs.Add(new Dog("Bob"));
            dogs.Add(new Dog("Adam"));
            dogs.Sort();
            foreach(Dog dog in dogs)
                Console.WriteLine(dog.Describe());
            Console.ReadKey();
        }
    }

    interface IAnimal
    {
        string Describe();

        string Name
        {
            get;
            set;
        }
    }

    class Dog : IAnimal, IComparable
    {
        private string name;

        public Dog(string name)
        {
            this.Name = name;
        }

        public string Describe()
        {
            return "Hello, I'm a dog and my name is " + this.Name;
        }

        public int CompareTo(object obj)
        {
            if(obj is IAnimal)
                return this.Name.CompareTo((obj as IAnimal).Name);
            return 0;
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

Начнем с середины, где мы объявляем интерфейс. Как видите, единственное отличие от объявления класса-ключевое слово used-interface вместо class. Кроме того, имя интерфейса предваряется префиксом I для интерфейса - это просто стандарт кодирования, а не требование. Вы можете называть свои интерфейсы как угодно, но поскольку они используются так часто как классы , что вам может быть трудно отличить некоторые части вашего кода, префикс I имеет довольно хороший смысл.

Затем мы объявляем метод Describe, а затем свойство Name, которое имеет как get, так и set ключевое слово, что делает это свойство доступным для чтения и записи. Вы также заметите отсутствие модификаторов доступа (public, private, protected и др.), и это потому, что они не разрешены в интерфейсе - все они являются общедоступными по умолчанию.

Следующий урок для нашего класса Dog. Обратите внимание, что это выглядит как наследование от другого класса, с двоеточием между именем класса и класса/интерфейса подкласса/реализованы. Однако в этом случае два интерфейса реализуются для одного класса, просто разделением запятой. Вы можете реализовать столько интерфейсов, сколько хотите, но в этом случае мы реализуем только два - наш собственный Интерфейс IAnimal и интерфейс .NET IComparable, который является общим интерфейсом для классов, которые можно сортировать. Теперь, как вы можете видеть, мы реализовали как метод, так и свойство из интерфейса IAnimal, а также метод CompareTo из интерфейса IComparable.

Теперь вы можете подумать: если мы должны делать всю работу самостоятельно, реализуя все методы и свойства, зачем вообще беспокоиться? И очень хороший пример того, почему это стоит вашего времени, приводится в верхней части нашего примера. Здесь мы добавляем кучу объектов Dog в список, а затем список сортируем. И как список знает, как сортировать собак? Потому что наш класс Dog имеет метод CompareTo, который может сказать, как сравнить двух собак. И как список знает, что наш собачий объект может сделать именно это, и какой метод вызвать, чтобы сравнить собак? Потому что мы так сказали, реализовав интерфейс, который обещает метод CompareTo! Это настоящая красота интерфейсов.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!