Чем полезны интерфейсы?
На самом деле, у меня есть [небольшое] представление о том, почему интерфейсы полезны / необходимы, но ...
Какие [интересные или реалистичные] приложения интерфейсов?
ну ... оба - есть ли разница?
Этот вопрос часто задают, вам следует поискать соответствующие вопросы.
извините, я надеялся, что этот вопрос найдет более практическое применение





Одно из применений, которое у меня есть для интерфейсов, - это помощь с классами фреймворка модульного тестирования, которые сложно имитировать. Я создам интерфейс, который работает в основном так же, как класс фреймворка и класс-оболочка, реализующий интерфейс. Конструктор класса-оболочки принимает в качестве аргумента экземпляр класса фреймворка. Оболочка делегирует функции интерфейса, которые она поддерживает, классу фреймворка, но я реализую его в своем интерфейсе, а не в фреймворке. Использование интерфейса позволяет мне смоделировать функциональность класса-оболочки в моих модульных тестах - либо используя имитирующую структуру, либо предоставляя поддельный класс, который также реализует интерфейс и поставляет его через внедрение зависимостей любым классам, которые обычно полагаются в классе framework.
Интерфейсы интересны тем, что вы можете позволить двум классам реализовать одни и те же методы. Давайте посмотрим на пример.
Скажем, у меня есть базовый класс Animal. Все животные дышат и общаются. Теперь предположим, что у меня есть 3 класса: Дельфин, Человек и Тигр. Все эти животные дышат и общаются. Но я хочу реализовать метод ходьбы для Человека и Тигра. Дельфины не умеют ходить. Поэтому я наследую метод IWalk для последних двух, и когда я компилирую класс, Я ДОЛЖЕН реализовать методы, указанные в интерфейсе, иначе он не будет компилироваться. Это контракт, в котором говорится: «Если я хочу реализовать этот класс, я должен реализовать эти методы».
-1: нет упоминания о том, какие интерфейсы реализуются. Вы имеете в виду «реализовать интерфейс IWalk», а не «унаследовать метод IWalk»?
@jamesbrady: в зависимости от вашего выбора языка (например, C++) вы наследуете интерфейс, ключевое слово реализации отсутствует. Будьте спортом и уберите -1, вопрос не зависит от языка.
Насколько это интересно или реально. Люди почти никогда не пишут классы, представляющие животных, кроме как для какого-то задания. Как это отмечено правильно, если оно не отвечает на исходный вопрос.
Они допускают полиморфизм без некоторых плохих сторон наследования.
Что я имею в виду под плохими сторонами наследства?
Код и данные унаследованы по длинной цепочке (что делает ее менее очевидной) .
Унаследованные члены, которые замещаются где-то в дереве наследования.
Как можно использовать полиморфизм?
Чтобы не повторяться. Создавайте функции, переключатели или условные выражения, которые используют интерфейс вместо объектов, реализующих интерфейс.
Специфичные для Java
В Java часто имеет смысл использовать интерфейсы как способ получения множественного наследования.
Это имеет смысл, если что-то естественным образом попадает в две категории, и для каждой из них ожидается разное поведение.
Некоторые примеры Java из Интернета
http://home.cogeco.ca/~ve3ll/jatutor5.htm
http://java.freehep.org/lib/freehep/doc/root/index.html
http://www.codeguru.com/java/tij/tij0080.shtml
Как упоминал tvanfosson, это очень полезно для имитации, также, если вы пишете библиотеку, которая зависит от внешней конфигурации, вы можете создать IFooProvider и заставить вызывающую программу реализовать его.
Я предполагаю, что вы имеете в виду "интерфейс" в смысле программирования язык, а не в других смыслах, например "Пользовательский интерфейс".
Интерфейс в таких языках, как Java или C#, служит двум целям. Первый - предоставить контракт для реализации типа; набор имен методов и сигнатур, которые тип предоставляет другим типам, которые его используют. Второй - обеспечить полиморфизм этого интерфейса для типа. Например, если у меня есть тип, реализующий интерфейс IFoo, я могу передать экземпляр этого типа другому классу, где другому классу нужно знать только об интерфейсе IFoo, а не о каждой детали моего класса, реализующего IFoo.
Интерфейсы полезны, когда вы хотите разрешить взаимодействие между двумя классами, которые не имеют общей иерархии классов.
Хороший пример этого - java.lang.CharSequence. Многие другие вещи можно абстрактно рассматривать как строки, но было бы неправильно создавать подкласс String для этого. На самом деле String является окончательным, так что это все равно невозможно.
Когда-то около JDK 1.4 (я полагаю?) Был представлен интерфейс CharSequence. Теперь String, StringBuffer, CharBuffer и множество других существующих классов в JDK реализуют его. При этом новые методы могут быть добавлены к другим API, которые принимают CharSequence, что позволяет им абстрактно обрабатывать все это унифицированным способом.
Вы также можете реализовать этот интерфейс самостоятельно и использовать его таким же образом. Гораздо более гибко реализовать общий интерфейс, чем пытаться заставить что-то расширяться от определенного базового класса (или иногда это невозможно).
Интерфейс (или абстрактный класс) - это контракт, который вы передаете компилятору. В этом контракте сказано:
- Что ж, компилятор, убедитесь, что все классы, которые будут это реализовывать, предоставят по меньшей мере все, что определено в этом интерфейсе!
Благодаря этой страховке вы можете написать методы, которые манипулируют объектами любого класса, реализующими этот интерфейс:
void myGenericMethod( IAnInterface genericObject )
Метод myGenericMethod может использовать любой член интерфейса IAnInterface. Он никогда не вызовет ошибку времени выполнения (любой отсутствующий член будет обнаружен компилятором).
Утилита: для придания некоторого общего поведения разным объектам. Например, вы можете захотеть вызвать метод с именем GetID для любого из ваших объектов, будь то BankAccount, ComputerCluster или AirplaneTrip.
Вы найдете множество полезных применений интерфейса в большинстве шаблонов проектирования. MSDN предоставляет несколько подсказок о том, когда вам следует использовать интерфейс здесь: http://msdn.microsoft.com/en-us/library/27db6csx.aspx
Я предпочитаю рассматривать интерфейс как описание роль, которое должно выполняться каждым экземпляром реализующего класса, независимо от какой-либо иерархии наследования реализации.
По аналогии, вы можете описать футбольную игру «проход с экрана» с точки зрения того, как взаимодействуют определенные позиции в команде. Это описание с точки зрения позиции (или роли, или интерфейса) не зависит от того, какой игрок играет эту позицию в данный момент. Также это не зависит от того, есть ли в команде несколько талантливых игроков, которые могут играть более чем на одной позиции.
Преимущество интерфейсно-ориентированного мышления состоит в том, что оно сосредотачивается на роли, которую объект выполняет в данном взаимодействии с другими объектами, без учета каких-либо других ролей, которые объект может играть в других видах взаимодействий. Это также позволяет тестированию сосредоточиться на сценариях, имеющих отношение к роли (и на имитации или подделке ролей в сценарии тестирования).
Вы имеете в виду особенности интерфейса Java или концепцию интерфейса?