Кодирование интерфейсов?

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

Очевидным преимуществом является знание функциональности, предоставляемой конкретным classом, независимо от ее конкретной реализации.

Исходя из вышесказанного:

  1. Есть ли какие-то заблуждения в моем понимании «кодирования для интерфейсов»?
  2. Есть ли какие-либо преимущества кодирования для интерфейсов, которые я пропустил?

Благодарю.

Только одна возможная коррекция:

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

Можно было бы назвать методы ссылкой на интерфейс типа, который использует конкретный class как реализацию:

List l = new ArrayList(); l.add("foo"); l.add("bar"); 

Если вы решили переключиться на другую реализацию List, код клиента работает без изменений:

 List l = new LinkedList(); 

Это особенно полезно для скрытия деталей реализации, автоматического создания прокси и т. Д.

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

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

Не имеет значения, является ли это SanDisk или Titanium (даже не уверен, что это бренд), размер и цвет тоже не имеют значения. На самом деле, единственное, что имеет значение, это то, что он не сломан (читается) и что он подключается к USB.

Ваш USB-накопитель соответствует контракту, это, по сути, интерфейс. Можно предположить, что он выполняет некоторые основные обязанности:

  1. Вкладыши в USB
  2. Abides по методу контракта CopyDataTo:

    public Interface IUSB {void CopyDataTo (строка somePath); // используется для копирования данных с миниатюрного диска в …}

  3. Abides по методу контракта CopyDataFrom:

    public Interface IUSB {void CopyDataFrom (); // используется для копирования данных с вашего ПК на миниатюрный диск}

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

 public class SanDiskUSB : IUSB { //todo: define methods of the interface here } 

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

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

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

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

Очевидным преимуществом является знание функциональности, предоставляемой конкретным classом, независимо от ее конкретной реализации.

Вроде. Самое главное, это позволяет писать API, которые берут параметры с типами интерфейсов. Пользователи API могут затем передавать свои собственные classы (которые реализуют эти интерфейсы), и ваш код будет работать на этих classах, даже если они еще не существовали, когда они были написаны (например, java.util.Arrays.sort () способный сортировать все, что реализует Comparable или поставляется с подходящим Comparator ).

С точки зрения дизайна интерфейсы позволяют / обеспечивают четкое разделение между контрактами API и деталями реализации.

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

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

Я думаю, вы могли намекнуть на это, но я считаю, что одним из самых больших преимуществ кодирования интерфейса является то, что вы нарушаете зависимость от конкретной реализации. Вы можете добиться ослабления связи и упростить передачу конкретных реализаций без изменения кода. Если вы просто учитесь, я бы рассмотрел различные шаблоны проектирования и то, как они решают проблемы путем кодирования интерфейсов. Чтение книги Head First: Design Patterns действительно помогли мне щелкнуть.

Насколько я понимаю, один создает интерфейсы для определения ожидаемой функциональности, а затем реализует эти «контракты» в конкретных classах.

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

Это позволит вам разложить свое мышление на polymorphism следующим образом.

 SoundMaker sm = new Duck();
SoundMaker sm1 = new ThunderousCloud(); sm.makeSound(); // quack, calls all sorts of stuff like larynx, etc.
sm1.makeSound(); // BOOM!, completely different operations here...
  • Почему мы не можем использовать это ключевое слово в статическом методе
  • C # код для ассоциации, агрегации, композиции
  • Как подключить одну панель к другой
  • Когда мне нужно использовать интерфейсы вместо абстрактных classов?
  • Почему инкапсуляция является важной особенностью языков ООП?
  • R и объектно-ориентированное программирование
  • В чем разница между абстрактной функцией и виртуальной функцией?
  • Почему мы используем интерфейс? Это только для стандартизации?
  • Что такое композиция, относящаяся к объектно-ориентированному дизайну?
  • Что скрывает метод в Java? Даже объяснение JavaDoc сбивает с толку
  • Интерфейс vs Базовый class
  • Давайте будем гением компьютера.