Почему я, может казаться, не схватываю интерфейсы?

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

52
задан Peter Mortensen 23 March 2018 в 06:07
поделиться

21 ответ

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

Думают о нем этот путь: Вы хотите обменяться данными с кем-то в кубе рядом с Вами, таким образом, Вы вытаскиваете свою палку флэш-памяти и скопировать/вставить. Вы идете по соседству, и парень говорит, "тот USB?" и Вы говорите да - весь набор. Размер палки флэш-памяти, ни производитель - все не имеет значения, что имеет значение, то, что это - USB.

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

public void Paint(Car car, System.Drawing.Color color)...

Это работало бы, пока Ваш клиент не сказал "теперь, что я хочу нарисовать грузовики", таким образом, Вы могли сделать это:

public void Paint (Vehicle vehicle, System.Drawing.Color color)...

это расширило бы Ваше приложение..., пока Ваш клиент не сказал "теперь, что я хочу нарисовать здания!" Что Вы, возможно, сделали, с самого начала создается интерфейс:

public interface IPaintable{
   void Paint(System.Drawing.Color color);
}

... и передал это Вашей стандартной программе:

public void Paint(IPaintable item, System.Drawing.Color color){
   item.Paint(color);
}

, Надо надеяться, это имеет смысл - это - довольно упрощенное объяснение, но надо надеяться добирается до сути его.

76
ответ дан Zaid 7 November 2019 в 08:57
поделиться

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

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

0
ответ дан Peter Mortensen 7 November 2019 в 08:57
поделиться

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

Позволяют нам видеть, помогает ли код:

public interface IReport
{
    void RenderReport(); // This just defines the method prototype
}

public abstract class Reporter
{
    protected void DoSomething()
    {
        // This method is the same for every class that inherits from this class
    }
}

public class ReportViolators : Reporter, IReport
{
    public void RenderReport()
    {
        // Some kind of implementation specific to this class
    }
}

public class ClientApp
{
    var violatorsReport = new ReportViolators();

    // The interface method
    violatorsReport.RenderReport();

    // The abstract class method
    violatorsReport.DoSomething();
}
1
ответ дан Peter Mortensen 7 November 2019 в 08:57
поделиться

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

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

, Например, последовательность, которой Вы интересуетесь, не имеет никакого отношения к первичным ключам в записях. С объектом, реализовывая интерфейс Вы могли сказать myObject.next () или myObject.prev ().

1
ответ дан fooledbyprimes 7 November 2019 в 08:57
поделиться

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

А хорошим примером реального мира был бы IDisposable в.NET. Класс, который реализует интерфейс IDisposable, вынуждает тот класс реализовать Расположение () метод. Если класс не реализует, Располагают (), Вы получите ошибку компилятора при попытке создать. Кроме того, эта кодовая комбинация:

using (DisposableClass myClass = new DisposableClass())
  {
  // code goes here
  }

вызовет myClass. Расположите (), чтобы быть выполненными автоматически, когда выполнение выйдет из внутреннего блока.

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

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

1
ответ дан Wedge 7 November 2019 в 08:57
поделиться

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

1
ответ дан David 7 November 2019 в 08:57
поделиться

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

Говорят, что Вы имеете:

public interface ICommand
{
    void Execute();
}
public class PrintSomething : ICommand
{
    OutputStream Stream { get; set; }
    String Content {get; set;}
    void Execute()
    { 
        Stream.Write(content);
    }
}

Теперь у Вас есть substitutable структура команды. Любой экземпляр класса, который реализует IExecute, может быть сохранен в каком-то списке, сказать что-то, что реализует IEnumerable, и можно циклично выполниться через это и выполнить каждого, зная, что каждый объект будет Просто Делай как надо. Можно создать составную команду путем реализации CompositeCommand, который будет иметь его собственный список команд для выполнения, или LoopingCommand для выполнения ряда команд неоднократно, тогда у Вас будет большая часть простого интерпретатора.

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

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

Ищут Liskov subsitution принцип, чтобы иметь больше смысла этого.

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

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

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

Как правило, я делаю интерфейс извлечения, осуществляющий рефакторинг, прежде чем я создам абстрактный класс. Я, более вероятно, создам абстрактный класс, если я буду думать, что должен быть контракт creational (а именно, что определенный тип конструктора должен всегда поддерживаться подклассами). Однако я редко использую "чистые" абстрактные классы в C#/java. Я, намного более вероятно, буду реализовывать класс по крайней мере с одним методом, содержащим значимое поведение, и использовать абстрактные методы поддерживать шаблонные методы, названные тем методом. Тогда абстрактный класс является базовым внедрением поведения, которое все конкретные подклассы могут использовать в своих интересах, не имея необходимость повторно реализовывать.

1
ответ дан JasonTrue 7 November 2019 в 08:57
поделиться

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

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

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

1
ответ дан user21334 7 November 2019 в 08:57
поделиться

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

1
ответ дан Eric Asberry 7 November 2019 в 08:57
поделиться

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

1
ответ дан Kevin Pang 7 November 2019 в 08:57
поделиться

Просто помещенный: интерфейс является классом, который методы определили только никакая реализация в них. По контрасту абстрактный класс имеет некоторые реализованные методы, но не все.

1
ответ дан Spoike 7 November 2019 в 08:57
поделиться

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

Интерфейсы описывают функциональность, не реализацию.

2
ответ дан Darren Kopp 7 November 2019 в 08:57
поделиться

Хорошо, таким образом, это об абстрактных классах по сравнению с интерфейсами...

Концептуально, абстрактные классы там, чтобы использоваться в качестве базовых классов. Довольно часто они сами уже обеспечивают некоторую основную функциональность, и подклассы должны обеспечить свою собственную реализацию абстрактных методов (те - методы, которые не реализованы в абстрактном базовом классе).

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

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

3
ответ дан Alexander 7 November 2019 в 08:57
поделиться

Интерфейсы являются также ключевыми для полиморфизма, одного из "ТРЕХ СТОЛБОВ OOD".

Некоторые люди, тронутые его выше, полиморфизм просто, подразумевают, что данный класс может взять различные "формы". Значение, если у нас есть два класса, "Собака" и "CAT" и оба, реализует интерфейс "INeedFreshFoodAndWater" (hehe) - Ваш код может сделать что-то вроде этого (псевдокод):

INeedFreshFoodAndWater[] array = new INeedFreshFoodAndWater[];
array.Add(new Dog());
array.Add(new Cat());

foreach(INeedFreshFoodAndWater item in array)
{
   item.Feed();
   item.Water();
}

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

4
ответ дан Sam Schutte 7 November 2019 в 08:57
поделиться

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

interface IReport
{
    string RenderReport();
}

class MyNewReport : IReport
{
    public string RenderReport()
    {
        return "Hello World Report!";

    }
}

class AnotherReport : IReport
{
    public string RenderReport()
    {
        return "Another Report!";

    }
}

//This class can process any report that implements IReport!
class ReportEmailer()
{
     public void EmailReport(IReport report)
     {
         Email(report.RenderReport());
     }
}

class MyApp()
{
    void Main()
    {
        //create specific "MyNewReport" report using interface
        IReport newReport = new MyNewReport();

        //create specific "AnotherReport" report using interface
        IReport anotherReport = new AnotherReport();

        ReportEmailer reportEmailer = new ReportEmailer();

        //emailer expects interface
        reportEmailer.EmailReport(newReport);
        reportEmailer.EmailReport(anotherReport);



    }

}
4
ответ дан Giovanni Galbo 7 November 2019 в 08:57
поделиться

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

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

Способность обратиться к сложной вещи с отдельным словом довольно полезна.

5
ответ дан Internet Friend 7 November 2019 в 08:57
поделиться

Это - "довольно длинный" предмет, но позвольте мне попытаться поместить его простой.

интерфейс - как, "они называют его" - Контракт. Но забудьте о том слове.

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

предположим у Вас есть приложение, которое обрабатывает сообщения. Сообщение содержит некоторый материал, как предмет, текст, и т.д.

, Таким образом, Вы пишете свой MessageController для чтения базы данных и сообщений извлечения. Это очень хорошо, пока Вы внезапно не слышите, что Факсы будут также скоро реализованы. Таким образом, необходимо будет теперь считать "Факсы" и обработать их как сообщения!

Это могло легко превратиться в код Spagetti. Таким образом, то, что Вы делаете вместо того, чтобы иметь MessageController, чем средства управления, "обменивается сообщениями" только, Вы делаете способным работать с интерфейс названный IMessage (я является просто общим использованием, но не требуемый).

интерфейс Your IMessage, содержит некоторые основные данные Вы потребность , чтобы удостовериться, что Вы в состоянии обработать сообщение как таковое.

Поэтому при создании электронной почты, Факса, классов PhoneCall, Вы делаете их Реализация Интерфейс названный IMessage.

Так в Вашем MessageController, можно было назвать метод как это:

private void ProcessMessage(IMessage oneMessage)
{
    DoSomething();
}

, Если бы Вы не использовали Интерфейсы, Вы должны были бы иметь:

private void ProcessEmail(Email someEmail);
private void ProcessFax(Fax someFax);
etc.

Так, при помощи распространенный интерфейс, Вы просто удостоверились, что метод ProcessMessage будет в состоянии работать с ним, неважно, если это был Факс, электронное письмо PhoneCall, и т.д.

Почему или как ?

, поскольку интерфейс контракт , который определяет некоторые вещи, Вы должны , придерживаются (или реализация), чтобы быть в состоянии использовать его. Думайте о нем как значок . Если бы Ваш объектный "Факс" не имеет интерфейса IMessage, то Ваш метод ProcessMessage не был бы в состоянии работать, с которым, это даст Вам недопустимый тип, потому что Вы передаете Факс методу, который ожидает объект IMessage.

Вы видите точку?

Думают об интерфейсе как о "подмножестве" методов и свойств, которые Вы будете иметь в наличии, несмотря на [1 141] реальный тип объекта. Если исходный объект (Факс, электронная почта, PhoneCall, и т.д.) реализации, которые взаимодействуют через интерфейс, Вы можете безопасность передавать его через методы та потребность тот Интерфейс.

существует больше волшебства, скрытого там, можно БРОСИТЬ интерфейсы назад к их исходным объектам:

Факс myFax = (Факс) SomeIMessageThatIReceive;

ArrayList () в.NET 1.1 имел хороший интерфейс под названием IList. Если бы у Вас был IList ("очень универсальный"), то Вы могли бы преобразовать его в ArrayList:

ArrayList ar = (ArrayList)SomeIList;

И существуют тысячи образцов там в дикой природе.

Интерфейсы как ISortable, IComparable, и т.д., определяют методы и свойства, Вы должны реализация в Вашем классе для достижения той функциональности.

Для расширения нашего образца у Вас мог быть List<> электронных писем, Факса, PhoneCall, всех в том же Списке, если Тип является IMessage, но у Вас не могло бы быть их всех вместе, если бы объекты были просто электронной почтой, Факсом, и т.д.

, Если бы Вы хотели отсортировать (или перечислить, например) Ваши объекты, Вам были бы нужны они для реализации соответствующего интерфейса. В образце.NET, если Вы имеете список объектов "Факса" и хотите быть в состоянии к вид их при помощи MyList. Вид (), Вы потребность для создания класса факса как это:

public class Fax : ISorteable 
{
   //implement the ISorteable stuff here.
}

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

предупреждение : Не все хорошо об интерфейсах, существует [приблизительно 1 110] проблемы с ними, пуристы ООП запустят войну с этим. Я останусь в стороне. Один недостаток Interfce (в.NET 2.0, по крайней мере) состоит в том, что у Вас не может быть Членов парламента, не занимающих официального поста, или защищенный, она должна быть общедоступной. Это имеет некоторый смысл, но иногда Вам жаль, что Вы не могли просто объявить материал как частный или защищенный.

6
ответ дан Martin Marconcini 7 November 2019 в 08:57
поделиться

Интерфейсы являются механизмом для сокращения связи между различным, возможно разрозненные части системы.

От .NET перспектива

  • интерфейсным определением является список операций и/или свойств.
  • Методы интерфейса всегда общедоступны.
  • сам интерфейс не должен быть общедоступным.

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

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

пример это немного более конкретно:

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

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

// First pass - not maintainable
void SubmitToWorkflow(object o, User u)
{
  if (o is StreetMap)
  {
     var map = (StreetMap)o;
     map.LastUpdated = DateTime.UtcNow;
     map.UpdatedByUser = u.UserID;
  }
  else if (o is Person)
  {
     var person = (Person)o;
     person.LastUpdated = DateTime.Now; // Whoops .. should be UtcNow
     person.UpdatedByUser = u.UserID;
  }
  // Whoa - very unmaintainable.

В коде выше, SubmitToWorkflow() должен знать о каждом объекте. Кроме того, код является путаницей с одним крупным if/else/switch, нарушает эти , не повторяют себя (DRY) принцип, и требует, чтобы разработчики помнили скопировать/вставить изменения каждый раз, когда новый объект добавляется к системе.

// Second pass - brittle
void SubmitToWorkflow(object o, User u)
{
  if (o is DTOBase)
  {
     DTOBase dto = (DTOBase)o;
     dto.LastUpdated = DateTime.UtcNow;
     dto.UpdatedByUser = u.UserID;
  }

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

// Third pass pass - also brittle
void SubmitToWorkflow(DTOBase dto, User u)
{
  dto.LastUpdated = DateTime.UtcNow;
  dto.UpdatedByUser = u.UserID;

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

Интерфейсы, как они могут помочь?

, Если мы определяем очень простой интерфейс:

public interface IUpdateTracked
{
  DateTime LastUpdated { get; set; }
  int UpdatedByUser { get; set; }
}

Любой класс, которому нужно это отслеживание автоматического обновления, может реализовать интерфейс.

public class SomeDTO : IUpdateTracked
{
  // IUpdateTracked implementation as well as other methods for SomeDTO
}

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

void SubmitToWorkflow(object o, User u)
{
  IUpdateTracked updateTracked = o as IUpdateTracked;
  if (updateTracked != null)
  {
     updateTracked.LastUpdated = DateTime.UtcNow;
     updateTracked.UpdatedByUser = u.UserID;
  }
  // ...
  • Мы можем отметить, что изменение void SubmitToWorkflow(IUpdateTracked updateTracked, User u) гарантировало бы безопасность типов, однако это не кажется как релевантное при этих обстоятельствах.

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

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

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

// Using an interface to bridge properties
public class LegacyDTO : IUpdateTracked
{
    public int LegacyUserID { get; set; }
    public DateTime LastSaved { get; set; }

    public int UpdatedByUser
    {
        get { return LegacyUserID; }
        set { LegacyUserID = value; }
    }
    public DateTime LastUpdated
    {
        get { return LastSaved; }
        set { LastSaved = value; }
    }
}

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

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

// Explicit implementation of an interface
public class YetAnotherObject : IUpdatable
{
    int IUpdatable.UpdatedByUser
    { ... }
    DateTime IUpdatable.LastUpdated
    { ... }

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

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

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

// Decouples the caller and the code as both
// operate only on IList, and are free to swap
// out the concrete collection.
public IList<T> FindDuplicates( IList<T> list )
{
    var duplicates = new List<T>()
    // TODO - write some code to detect duplicate items
    return duplicates;
}

протест Управления версиями

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

См. это сообщение Haacked для хорошего обсуждения.

Интерфейсы по сравнению с абстрактными (основными) классами

Абстрактные классы могут обеспечить реализацию, тогда как Интерфейсы не могут. Абстрактные классы до некоторой степени более гибки в аспекте управления версиями, если Вы следуете некоторым инструкциям как NVPI (Невиртуальный Открытый интерфейс) шаблон.

стоит повторить, что в.NET, класс может только наследоваться единому классу, но класс может реализовать столько интерфейсов, сколько этому нравится.

Внедрение зависимости

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

class AnnualRaiseAdjuster
   : ISalaryAdjuster
{
   AnnualRaiseAdjuster(IPayGradeDetermination payGradeDetermination) { ...  }

   void AdjustSalary(Staff s)
   {
      var payGrade = payGradeDetermination.Determine(s);
      s.Salary = s.Salary * 1.01 + payGrade.Bonus;
   }
}

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

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

14
ответ дан 7 revs, 4 users 82% 7 November 2019 в 08:57
поделиться

При вождении автомобиля друга Вы более или менее знаете, как сделать это. Это вызвано тем, что стандартные автомобили у всех есть очень похожий интерфейс: руль, педали, и т.д. Думайте об этом интерфейсе как о контракте между автопроизводителями и драйверами. Как драйвер (пользователь/клиент интерфейса в условиях программного обеспечения), Вы не должны изучать подробные сведения различных автомобилей, чтобы быть в состоянии управлять ими: например, все, что необходимо знать, - то, что превращение руля заставляет автомобиль повернуться. Как автопроизводитель (поставщик реализации интерфейса в условиях программного обеспечения) у Вас есть четкое представление, что должен иметь Ваш новый автомобиль и как это должно вести себя так, чтобы драйверы могли использовать их без большого дополнительного обучения. Этот контракт - то, что люди в разработке программного обеспечения называют разъединяющийся (пользователь от поставщика) - клиентский код с точки зрения использования интерфейса, а не конкретной реализации этого и следовательно не должен знать детали объектов, реализовывая интерфейс.

16
ответ дан Alexander 7 November 2019 в 08:57
поделиться

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

Public Interface IRollOver
    Sub RollOver()
End Interface

Public Class Dog Implements IRollOver
    Public Sub RollOver() Implements IRollOver.RollOver
        Console.WriteLine("Rolling Over!")
    End Sub
End Class

Public Sub Main()
    Dim d as New Dog()
    Dim ro as IRollOver = TryCast(d, IRollOver)
    If ro isNot Nothing Then
        ro.RollOver()
    End If
End Sub

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

33
ответ дан Bob King 7 November 2019 в 08:57
поделиться

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

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

, Таким образом, Вы знаете, домашние животные могут сделать определенные вещи. Они могут спать или поесть, и т.д. Таким образом, Вы определяете интерфейс под названием IPet, и он выглядит примерно так (синтаксис C#)

public interface IPet
{
    void Eat(object food);
    void Sleep(int duration);
}

Каждая Ваша Собака, CAT, и классы Мыши реализуют IPet.

public class Dog : IPet

Поэтому теперь каждый из тех классов должен иметь свою собственную реализацию, Едят и Сон. Yay у Вас есть контракт... Теперь какой смысл.

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

public class PetStore
{
     public static IPet GetRandomPet()
     {    
          //Code to return a random Dog, Cat, or Mouse
     } 
}

IPet myNewRandomPet = PetStore.GetRandomPet();
myNewRandomPet.Sleep(10);

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

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

45
ответ дан JoshReedSchramm 7 November 2019 в 08:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: