Является ли программирование против интерфейсов в Java той же концепцией, что и использование файлов заголовков в C/С++?

В java-коде, на котором я сейчас работаю, часто есть структура вроде

file Controller.java:

interface Controller {...}

file ControllerImpl.java:

class ControllerImpl implements Controller {...}

Но для каждого интерфейса существует только одна реализация. Разве это не так, как использование файлов заголовков в C/С++, где у меня есть код, разбитый на такие файлы, как

Controller.hpp
Controller.cpp

Из того, что я знаю, были добавлены файлы заголовков в C/С++, чтобы помочь компилятору, который больше не нужен в Java. Также заголовочные файлы должны помочь с удобочитаемостью кода, но наличие современной среды разработки с откидным и контурным просмотром также не является необходимостью.

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

Ответ 1

Нет. В С++ файлы (заголовки) не совпадают с классами.

Программирование на интерфейсах, как в Java, может быть выполнено и на С++, программируя против абстрактных базовых классов.

Однако термин Java "интерфейс" довольно ограничен. В принципе, любое объявление функции - это интерфейс:

void call_me(int times); 

Как и, конечно, классы и другие типы.

В С++ вы группируете такие вещи в заголовках, поэтому интерфейс может состоять из одного заголовка. Однако он может состоять из нескольких заголовков.

Ответ 2

Интерфейсы не связаны с желанием хранить файлы заголовков.

Интерфейсы ближайшего Java к поддержке http://en.wikipedia.org/wiki/Design_by_contract

Ответ 3

Интерфейсы

больше похожи на абстрактные базовые классы в С++.

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

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

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

Ответ 4

В Java интерфейс определяет контракт, а класс предоставляет реализацию контракта.

Большинство контрактов имеют только одну значимую или соответствующую реализацию; некоторые даже предполагают конкретную реализацию и не допускают других. Эти контракты и их реализации определяются вместе в классах без каких-либо интерфейсов. Пример: java.lang.String.

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

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

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

Ответ 5

Вопрос хороший, есть связь между файлами заголовков и классами/интерфейсами/программированием OO, помимо исходного синтаксиса языков.

Правильный дизайн программы на С++:

  • Поместите одно объявление класса и одно только в h файле.
  • Дайте указанному h файлу то же имя, что и объявлен класс.
  • Поместите определение класса в cpp файл с тем же именем, что и ч файл.

Правильный дизайн программы Java:

  • То же, что и для С++, хотя и помещает интерфейсы в свои собственные файлы.

Правильный дизайн C:

  • В h файле объявить функции, относящиеся к определенному "модулю кода".
  • Поместите определения функций в c файл с тем же именем, что и h файл.
  • Все переменные, которые вы бы объявили как конфиденциальные/защищенные, если запись С++/Java должна быть действительно конфиденциальной по понятию "непрозрачный тип/указатели" или быть помещена в область файла и объявлена ​​как статическая, чтобы они могли быть разделены между функциями в "модуле кода" (хотя это делает код не реентерабельным).

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

Ответ 6

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

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

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

Эта ограниченная поддержка оставила Java с ключевым словом interface: поскольку ориентация объектов связана с группировкой функциональности в классы, имеет смысл связать концепцию "интерфейса" с тем, что определяет определения функций членов группы. Несколько классов могут реализовать данный интерфейс, а класс может также реализовать множество интерфейсов.

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

Когда дело доходит до разделения вашего кода на заголовки и исходные файлы, это совершенно не имеет отношения к концепции интерфейса. Но действительно: в С++ "контракт на вызов" в основном указывается в файле заголовка. И действительно, это сокращает время компиляции (меньше IO). Но это компилятор-технический аспект.

Ответ 7

Заголовочные файлы в C/С++ не имеют ничего общего с классами или интерферами.

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

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

Заголовочный файл на С++ может содержать классы или определения функций, макросы или перечисления или многое другое, но концептуально отличается от классов или интерфейсов.

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

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

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