Подтвердить что ты не робот

В чем разница между интерфейсом и классом, и почему я должен использовать интерфейс, когда я могу реализовать методы непосредственно в классе?

Я знаю, что это очень простой вопрос, но интервьюер спросил меня очень трюк, и я был беспомощным: (

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

Я также не понимаю одну вещь в интерфейсе. например, мы используем

conn.Dispose(); в блоке finally. Но я не вижу, что класс реализует или наследует IDisposable интерфейс (SqlConnection) класс I. Мне интересно, как я могу просто назвать имя метода. Также в том же, я не понимаю, как работает метод Dispose, потому что нам нужно реализовать тело функции с нашей собственной реализацией для всех методов интерфейса. Итак, как интерфейсы принимаются или называются контрактами? Эти вопросы продолжались до сих пор, и, честно говоря, я никогда не видел ни одной хорошей нити, которая могла бы объяснить мои вопросы таким образом, чтобы я мог понять.

MSDN как обычно выглядит очень страшно, и там нет единой строки (люди, любезно извините, кто находится на высоком уровне развития, я твердо чувствую, что любой код или статья должны доходить до ума любого, кто его видит, следовательно, как и многие другие скажем, MSDN не используется).

Интервьюер сказал:

У него есть 5 методов, и он счастлив реализовать его в классе напрямую, но если вам нужно перейти на абстрактный класс или интерфейс, какой из них выбрать и почему? Я ответил ему на все материалы, которые я читал в разных блогах, говоря о преимуществах и недостатках как абстрактного класса, так и интерфейса, но он не убежден, он пытается понять "Почему интерфейс" в целом. "Почему абстрактный класс" вообще, даже если я могу реализовать одни и те же методы только один раз, а не изменять его.

Я не вижу места в сети, я мог бы получить статью, которая бы четко объяснила мне об интерфейсах и его функционировании. Я один из тех многих программистов, которые до сих пор не знают об интерфейсах (я знаю теоретические и методы, которые я использовал), но не удовлетворены тем, что я это ясно понял.

4b9b3361

Ответ 1

Интерфейсы превосходны, когда вы хотите создать что-то вроде этого:

using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a specific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as a parameter any object that implements IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

В моем примере я мог быть разработчиком, который пишет MyLogClass, а другие разработчики могли создавать свои классы, и когда они хотели войти, они реализовывали интерфейс IMyLogInterface. Это как они спрашивали меня, что им нужно реализовать, чтобы использовать метод WriteLog() в MyLogClass. Ответ они найдут в интерфейсе.

Ответ 2

Одна из причин, по которой я использую интерфейсы, заключается в том, что это увеличивает гибкость кода. Допустим, у нас есть метод, который принимает объект класса типа Account в качестве параметра, например:

public void DoSomething(Account account) {
  // Do awesome stuff here.
}

Проблема с этим заключается в том, что параметр метода фиксирован для реализации учетной записи. Это хорошо, если вам никогда не понадобится аккаунт другого типа. Возьмите этот пример, который вместо этого использует интерфейс учетной записи в качестве параметра.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

Это решение не привязано к реализации, что означает, что я могу передать ему SuperSavingsAccount или ExclusiveAccount (оба реализуют интерфейс IAccount) и получить различное поведение для каждой реализованной учетной записи.

Ответ 3

Интерфейсы - это контракты, которым должны следовать исполнители. Абстрактные классы позволяют заключать контракты плюс общие реализации - то, чего не могут иметь интерфейсы. Классы могут реализовывать и наследовать несколько интерфейсов. Классы могут расширять только один абстрактный класс.

Почему интерфейс

  • У вас нет реализации по умолчанию или общего кода
  • Вы хотите поделиться контрактами с данными (веб-сервисы, SOA).
  • У вас есть разные реализации для каждого разработчика интерфейса (IDbCommand имеет SqlCommand и OracleCommand, которые реализуют интерфейс по-разному)
  • Вы хотите поддерживать множественное наследование.

Почему Аннотация

  • У вас есть реализация по умолчанию или общий код.
  • Вы хотите свести к минимуму дублирование кода.
  • Вы хотите легко поддерживать версию.

Ответ 4

enter image description here

Так что в этом примере PowerSocket больше ничего не знает о других объектах. Все объекты зависят от мощности, предоставляемой PowerSocket, поэтому они реализуют IPowerPlug и при этом могут подключаться к нему.

Интерфейсы полезны, потому что они предоставляют контракты, которые объекты могут использовать для совместной работы, без необходимости знать что-либо еще друг о друге.

Ответ 5

В одном слове - из-за Полиморфизма!

Если вы "Программируете интерфейс, а не реализацию", вы можете вводить разные объекты, которые используют один и тот же интерфейс (тип) в качестве аргумента. Таким образом, ваш код метода не связан с какой-либо реализацией другого класса, что означает, что он всегда открыт для работы с вновь созданными объектами того же интерфейса. (Принцип открытия/закрытия)

  • Посмотрите на Injection Dependency и определенно прочитайте Design Patterns - Элементы многоразового объектно-ориентированного программного обеспечения GOF.

Ответ 6

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

Ответ 7

С помощью интерфейса вы можете сделать следующее:

1) Создайте сегрегированные интерфейсы, которые предлагают различные сокращения вашей реализации, позволяя использовать более сплоченный интерфейс.

2) Разрешить использование нескольких методов с одним и тем же именем между интерфейсами, потому что, у вас нет противоречивой реализации, просто подпись.

3) Вы можете выполнить версию и убрать свой интерфейс независимо от своей реализации, гарантируя, что контракт будет выполнен.

4). Ваш код может полагаться на абстракцию, а не на конкрецию, что позволяет осуществлять интеллектуальную инъекцию, включая инъекционные тестовые Mocks и т.д.

Есть еще много причин, я уверен, это всего лишь несколько.

Абстрактный класс позволяет иметь частично конкретную базу для работы, это не то же самое, что интерфейс, но имеет свои собственные качества, такие как возможность создания частичной реализации с использованием шаблона метода шаблона.

Ответ 8

Я считаю, что много крови уже было пролито, задавая эти вопросы, и многие пытаются решить эти проблемы, объясняя роботоподобные термины, которые ни один нормальный человек не может понять.

Итак, сначала. узнать, почему интерфейс и почему абстракция вам нужно узнать, для чего они нужны. Я лично узнал об этом при применении класса Factory. вы найдете хороший tuturial по этой ссылке

Теперь дайте ссылку на ссылку на ссылку, которую я уже дал.

У вас есть класс Автомобиль, который может измениться по требованию пользователя (например, добавить Truck, Tank, Airplane и т.д. И если у нас есть

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

и

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

и оба имеют контракт IChoice, который просто говорит, что мой класс должен иметь метод Buy

public interface IChoice
{
    string Buy();
}

Теперь вы видите, что этот интерфейс только применяет метод Buy(), но позволяет унаследованному классу решить, что делать, когда они его реализуют. Это ограничение интерфейса, используя чисто интерфейс, вы можете в конечном итоге повторить некоторую задачу, которую мы можем реализовать автоматически, используя abstact. На нашем примере допустим, что у каждого автомобиля есть скидка.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

Теперь, используя класс Factory, вы можете добиться того же, но используя абстрактное, вы позволяете базовому классу выполнять метод Buy().

В сводке: контракты Интерфейс позволяют классу inherit выполнять реализацию   в то время как Абстрактный класс Контракты могут инициализировать реализацию (которая может переопределяться классом Inherit)

Ответ 9

Как реальный пример ответа @user2211290:

Оба из Array и List имеют интерфейс IList. Ниже у нас есть string[] и List<string> а также несколько общих тестов с использованием IList:

string[] col1 = { "zero", "one", "two", "three", "four"};
List<string> col2 = new List<string>{ "zero", "one", "two", "three"};

static void CheckForDigit(IList collection, string digit)
    {
        Console.Write(collection.Contains(digit));
        Console.Write("----");
        Console.WriteLine(collection.ToString());
    }

static void Main()
{
    CheckForDigit(col1, "one");   //True----System.String[]
    CheckForDigit(col2, "one");   //True----System.Collections.Generic.List'1[System.String]



//Another test:

    CheckForDigit(col1, "four");   //True----System.String[]
    CheckForDigit(col2, "four");   //false----System.Collections.Generic.List'1[System.String]
}

Ответ 10

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

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

Ответ 11

Оба абстрактного класса и интерфейса - это контракты.

Идея контракта заключается в том, что вы указываете какое-то поведение. Если вы говорите, что вы выполнили, вы согласились на контракт.

Выбор абстрактного над интерфейсом.

Любой абстрактный объект абстрактного класса реализует контракт.

против

Любой класс, реализующий интерфейс, будет выполнять контракт.

Итак, вы используете абстрактный, когда хотите указать какое-либо поведение, все потомки должны реализовать и сохранить себя, определяя отдельный интерфейс, но теперь все, что соответствует этому эффективно агрегированному контракту, должно быть потомком.

Ответ 12

Интерфейсы предназначены для создания абстракции (архетипа) абстракции (классов) реальности (объектов).

Интерфейсы должны указывать условия договора без предоставления реализации, предоставляемой классами.

Интерфейсы имеют технические характеристики:

  • Интерфейсы - это артефакты времени разработки, которые определяют неподвижное поведение концепции, поскольку оно одно и статично.

  • Классы - это артефакты времени реализации, которые определяют мобильную структуру реальности, когда она взаимодействует и движется.

Что такое интерфейс?

Когда вы наблюдаете за кошкой, вы можете сказать, что это животное с четырьмя лапами, головой, туловищем, хвостом и шерстью. Вы можете видеть, что он может ходить, бегать, есть и мяу. И так далее.

Вы только что определили интерфейс с его свойствами и операциями. Таким образом, вы не определили какой-либо способ действия, а только функции и возможности, не зная, как все работает: вы определили способности и различия.

Как таковой, он на самом деле еще не является классом, хотя в UML мы называем его классом на диаграмме классов, потому что мы можем определить рядовые и защищенные члены, чтобы начать глубже рассматривать артефакт. Не путайте здесь, потому что в UML интерфейс немного отличается от интерфейса в С#: он похож на частичную точку доступа к атому абстракции. Таким образом, мы сказали, что класс может реализовывать несколько интерфейсов. Как таковая, это одно и то же, но не потому, что интерфейсы в С# используются как для абстракции, так и для ограничения этой абстракции в качестве точки доступа. Это два разных использования. Таким образом, класс в UML представляет интерфейс полной связи с классом программирования, тогда как интерфейс UML представляет интерфейс развязки раздела класса программирования. Действительно, диаграмма классов в UML не заботится о реализации, и все ее артефакты находятся на уровне интерфейса программирования. Хотя мы отображаем UML-классы на классы программирования, это перенос абстрактной абстракции в конкретную абстракцию. Есть тонкость, которая объясняет дихотомию между областью дизайна и областью программирования. Таким образом, класс в UML является классом программирования с точки зрения интерфейса программирования с учетом внутренних скрытых вещей.

Интерфейсы также позволяют имитировать множественное наследование, когда оно недоступно неудобным способом. Например, класс cat будет реализовывать интерфейс cat, который наследуется от интерфейса животного. Этот класс cat также будет реализовывать эти интерфейсы: ходить, бегать, есть и издавать звук. Это компенсирует отсутствие множественного наследования на уровне класса, но каждый раз вам нужно все переопределять, и вы не можете в лучшем случае учитывать реальность, как это делает сама реальность.

Чтобы понять, что мы можем обратиться к кодированию Pascal Object, где вы определяете в модуле интерфейс и разделы реализации. В интерфейсе вы определяете типы, а в реализации вы реализуете тип:

unit UnitName;

interface

type
  TheClass = class
  public
    procedure TheMethod;
  end;

implementation

class procedure TheClass.TheMethod;
begin
end;

Здесь раздел интерфейса соответствует дизайну класса UML, в то время как типы интерфейсов, таким образом, являются другими вещами.

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

Кроме того, в С#, например, программные интерфейсы позволяют компенсировать отсутствие истинного универсального полиморфизма в открытых типах без реального достижения цели, потому что вы потеряли строгую типизацию.

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

Что такое класс?

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

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

Таким образом, абстрактный класс каким-то образом является эквивалентом интерфейса с точки зрения компилятора.

Дополнительная информация

Протокол (объектно-ориентированное программирование)

С# - Интерфейсы

С# - Классы

Ответ 13

Интерфейсы позволяют дизайнеру класса сделать доступными методы очень понятными для конечного пользователя. Они также являются неотъемлемой частью полиморфизма.

Ответ 14

Я не буду публиковать определение интерфейса против абстрактного класса, потому что я думаю, что вы хорошо знаете эту теорию, и я предполагаю, что вы знаете принципы SOLID, поэтому давайте начнем практиковать.

Как вы знаете, интерфейсы не могут иметь никакого кода, поэтому dis-vantage довольно просто понять.

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

Итак, в общем случае вы должны предпочесть абстрактный класс для интерфейсов, когда вам нужно предоставить конструктору или любому коду клиенту, который наследует/расширяет ваш класс

Ответ 15

Абстрактный класс разбивается на категории для связанных объектов, где в качестве интерфейсов могут использоваться не связанные между собой объекты.

Например, если у меня есть две сущности, скажем, Animal and Human, то я пойду для интерфейса, где, как если бы я должен подробно остановиться на Tiger, lion и хочу связать с Animal, тогда выберем Animal Abstract class..

будет выглядеть ниже

   Interface             
   ____|____
  |        |
Animal   Human



  Animal (Abstract class)
   __|___
  |      |
Tiger   Lion