У меня есть домашнее задание, и мне нужно оценить, какой подход лучше в соответствии с GRASP «Защищенное изменение». Я нашел вопрос о переполнении стека о разделении файлов заголовка и кода в C ++ .
Тем не менее, я хочу знать, почему Java не следует C ++ в продвижении разделения между определениями классов и реализациями классов. Есть ли какие-либо преимущества у метода Java по сравнению с методом C ++?
java
programming-languages
c++
Этьен Ноэль
источник
источник
private
, поэтому реализация будет знать размер, а такжеprivate
функции-члены.Ответы:
Сколько строк кода в следующей программе?
Вы, вероятно, ответили 7 (или 6, если вы не считали пустую строку, или 4, если вы не считали скобки).
Ваш компилятор, однако, видит что-то совсем другое:
Да, это 18,7 KLOC только для "Привет, мир!" программа. Компилятор C ++ должен проанализировать все это. Это главная причина, почему компиляция C ++ занимает так много времени по сравнению с другими языками, и почему современные языки избегают заголовочных файлов.
Лучший вопрос будет
Почему же C ++ есть файлы заголовков?
C ++ был разработан, чтобы быть надмножеством C, поэтому он должен был хранить заголовочные файлы для обратной совместимости.
Хорошо, так почему C имеет заголовочные файлы?
Из-за своей примитивной отдельной модели компиляции. Объектные файлы, сгенерированные компиляторами C, не содержат никакой информации о типе, поэтому для предотвращения ошибок типа вам необходимо включить эту информацию в ваш исходный код.
Добавление правильных объявлений типов исправляет ошибку:
Обратите внимание, что нет
#include
s. Но когда вы используете большое количество внешних функций (что делает большинство программ), их ручное объявление становится утомительным и подверженным ошибкам. Гораздо проще использовать заголовочные файлы.Как современные языки могут избежать заголовочных файлов?
Используя другой формат объектного файла, который включает информацию о типе. Например, формат файла Java * .class включает «дескрипторы», которые определяют типы полей и параметры метода.
Это не было новым изобретением. Ранее (1987), когда Borland добавил отдельно скомпилированные «модули» в Turbo Pascal 4.0, он решил использовать новый
*.TPU
формат, а не Turbo C,*.OBJ
чтобы устранить необходимость в заголовочных файлах.источник
OBJ
файлов, а неTPU
s ...У Java есть интерфейсы для определения контракта. Это дает более высокий уровень абстракции от того, что нужно вызывающей стороне и фактической реализации. то есть вызывающему не нужно знать реализующий класс, ему нужно только знать контракт, который он поддерживает.
Скажем, вы хотите написать метод, который замедляет все ключи / значения на карте.
Этот метод может вызывать entrySet () для абстрактного интерфейса, который удален из реализующего его класса. Вы можете вызвать этот метод с помощью.
источник
#define interface class
.virtual
ключевое слово для получения полиморфизма, и это не снижает производительности, если вы используете только один или два конкретных типа, как в Java. Можете ли вы указать мне какую-либо документацию о том, как это работает в C ++?Заголовки существуют, прямо скажем, как историческая случайность. Это невероятно плохая система, ни на одном другом языке нет ничего настолько ужасного, и любой, кому не приходится иметь с ними дело, должен радоваться.
источник
Заголовки предназначены для отдельной компиляции. За счет #include заголовков компилятору не нужно ничего знать о двоичной структуре скомпилированного кода C ++, и он может оставить это задание отдельному компоновщику. Java не использует отдельный компоновщик со своим компилятором, и поскольку файлы .class строго определены, компилятор может читать их, чтобы определить всех их членов со всеми их типами, без необходимости повторного объявления их в каждом модуле компиляции.
Вы можете включить всю реализацию в заголовок C ++, но это заставляет компилятор перекомпилировать его каждый раз, когда он #included, заставляя компоновщик разбирать и отбрасывать дубликаты.
источник
Java способствует разделению определения класса и реализации, это просто зависит от того, откуда вы смотрите.
Когда вы являетесь автором класса Java, вы можете увидеть определение класса и его реализацию в одном файле. Это упрощает процесс разработки, так как вам нужно только перейти в одно место для поддержки класса, вам не нужно переключаться между двумя файлами (.h и .cpp, как в C ++). Однако, когда вы являетесь потребителем класса, вы имеете дело только с определением через файл .class, который упакован в .jar или в отдельный .class
C ++ позволяет разделить определение и реализацию, но это специальное решение. Например, ничто не мешает вам писать метод, встроенный в заголовочный файл, а для шаблонных классов это обязательно. В заголовочном файле также перечислены все переменные-члены, которые видны всем, кто просматривает заголовочный файл, даже если они являются подробностями реализации класса и не имеют отношения к потребителю.
источник