C ++中的头文件和Java中的抽象类/接口实现是否一致是正确的吗?

我有点熟悉C ++,我知道对于几乎每个头文件,我都必须创建源文件。

现在我正在研究java接口和实现,它看起来是一样的。 首先,您只需在一个类中命名变量和方法,然后在其他类中定义它们。

这些东西在C ++和Java中是基本相同还是相似?

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文件,只查看#included头文件。

Java接口等同于C ++抽象基类。 它本质上是一组方法的声明,包括它们采用的参数类型和返回值的类型。 Java接口或C ++抽象基类可以由Java类或C ++类inheritance,它实际上定义(实现)这些方法是什么。

在C ++中,当您创建类时,通常(有exception)将方法声明放入头文件中,并将定义放在.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; } }; 

NO,接口是一种构造,甚至作为抽象类存在于c ++中。 它与.hpp和.cpp文件中的拆分无关。 接口定义了一组函数,然后可以被子类/实现覆盖

不,他们是完全不同的。

Java没有等同于“头文件”:API /数据结构的声明和类的实现的分离根本就不存在。 如果你想引用一些第三方类,那么你将需要.class文件,这与你想要运行第三方类时所需的完全相同(注意它们通常存储在.jar文件中) ,但这只是为了方便)。

C ++与Java接口最接近的是纯虚拟类:即定义一组方法但不定义任何实现的类。 就像在Java中一样,你必须为它们生成一些子类才真正有用,这些子类将提供实现。

他们是非常不同的。

Java接口更像是C ++中的纯抽象类,其中没有一个方法具有实现。 它们用作与对象的契约,以保证可以调用方法。

接口存在的关键原因是Java没有多重inheritance ,这意味着一个类只能扩展一个超类。 但是,类可以实现多个接口,因此您可以通过任意数量的接口定义可以在类上执行的任意数量的操作。

并不是的。

首先,Java接口不能包含变量,只能包含常量和方法。

其次,Java接口应该只在必要时创建,即你有一个多个类实现的API,并且你希望能够编写统一处理它们的代码。 大多数Java类不应具有匹配的接口,并且大多数Java接口应具有两个或更多实现类。

没有头文件主要包含我们可以在某处使用的代码,一些接口如何只是一个契约应该如何实现它不一样的

C ++很老,它是基于C构建的,它甚至更老。 在C ++中,类实际上是一个C风格的struct ,带有指向vtable的指针,包含指向类中每个函数的起始地址的指针。

你在头文件中放的是类的定义,即结构。 您在我们的实现中添加的是vtable指向的function。 这就是为什么你需要在另一个文件中包含一个类的定义(“标题”)才能使用它。 这也是您通常将类的定义放在单独的文件(.hpp)中的原因。 您严格不必,但如果不这样,则很难在其他类中使用该类。 但是你也可以将所有代码放在一个大文本文件中。

C ++编译器将独立处理每个文件,扩展所有#include宏以在每个.cpp文件中包含它们的定义。 它还会将所有函数调用转换为vtable表示法,即

someInstance-> someMethod()变为(someInstance-> VTABLE [0]),假设someMethod()是someIntance类定义中声明的第一个。

然后,编译器创建目标文件(所谓的转换单元),并在内存布局中为所有.cpp文件中实现的所有函数生成所得到的加工代码,并为所有vtable中的所有指针提供重定位表。 稍后,链接器会将重定位表中的符号解析为函数的实际内存地址。

简而言之,C ++看起来就像传统目的一样(事实上C不是面向对象的)。 Java是面向对象的,这意味着接口是你可以使用的东西,而不是C ++,其中类定义是你必须拥有的东西(struct和vtable,记住)以及你必须以某种方式包含的东西。 .cpp文件,您要在哪个类中使用该类。