Правильно ли, что заголовочные файлы в C++ и абстрактные реализации классов/интерфейсов в Java-это одна и та же идея?

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

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

являются ли эти вещи в C++ и Java в основном одинаковыми или похожими?

8 ответов


интерфейсы Java и файлы заголовков/реализации C++ - это разные концепции.

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

функции в C++ могут быть объявил просто пишешь имя функции и аргументы:

void PrintMessage(std::string text);

и они могут быть определена написав тело метода тоже:

void PrintMessage(std::string text)
{
  cout << text;
}  

вы можете определить функцию только один раз в блоке компиляции (это весь текст, который компилятор видит после того, как #includes были заменены текстом файла, который они включают). Но вы можете объявить функцию во много раз дольше, чем заявления те же самые. Вы должны определить каждую функцию, которая вызывается один раз. Вот почему у тебя есть э .cpp-файл для каждого .H-файл. Этот.cpp определяет все функции, которые объявлены в.H-файл. Этот.H-файл включается во все .cpp файлы, которые используют функции и включается один раз в.cpp-файл, определяющий функции.

Java работает, где определения функций для вас, когда он компилирует проект, как он смотрит на все файлы в проект. C++ компилирует только один .cpp-файл за раз и только смотрит на # включенные заголовочные файлы.

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

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


нет. В Java interface является абстрактным классом C++. Рассматривайте это:

// Java
interface Entity {
  void func();
}

class EntityImpl implements Entity {
  public void func() {
    System.out.println("func()");
  }
}

и

// C++
struct Entity {
  virtual void func() = 0;
  virtual ~Entity() {}

// just to emphasize it's a BASE class
protected: Entity() {} // not required
};

struct EntityImpl : Entity {
  void func() {
    std::cout << "func()" << std::endl;
  }
};

нет, интерфейс-это конструкция, которая даже существует в c++ как абстрактные классы. Это не имеет никакого отношения к расколу .ГЭС и. cpp-файлы. Интерфейс определяет некоторый набор функций, которые затем могут быть переопределены дочерними классами / реализацией


нет, они совершенно разные.

Java не имеет эквивалента "файлу заголовка": разделение декларация API / структур данных и реализация ваших классов просто не существует. Если вы хотите ссылаться на некоторые сторонние классы, вам понадобится .class файлы, которые точно то же самое, что вам нужно, когда вы хотите run классы сторонних производителей (обратите внимание, что они обычно хранятся в .jar файлы, но это просто для удобства).

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


Они очень разные.

интерфейс Java больше похож на чистый абстрактный класс В C++, где ни один из методов не имеет реализаций. Они служат в качестве контракта с объектом, чтобы гарантировать, что методы могут быть вызваны.

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


Не совсем так.

во-первых, интерфейс Java не может содержать переменные, только константы и методы.

во-вторых, интерфейсы Java должны создаваться только там, где это необходимо, т. е. там, где у вас есть API, реализуемый несколькими классами, и вы хотите иметь возможность писать код, который обрабатывает их равномерно. Большинство Java-классов не имеют соответствующий интерфейс, и большинство интерфейсов Java должны иметь два или более реализующих классов.


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


C++ старый, и он построен на C, который еще старше. В C++ класс действительно является C-style struct с указателем на vtable, содержащий указатели на начальный адрес каждой функции в классе.

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

компилятор C++ будет обрабатывать каждый файл независимо, расширяя все макросы #include, чтобы включить их определения в каждый .файл cpp. Он также переведет все вызовы функций в нотацию vtable, т. е.

someInstance->someMethod() становится (someInstance - >VTABLE[0]), предполагая, что someMethod() является первым, объявленным в определении класса someIntance.

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