c++中的头文件和Java中的抽象类/接口实现是相同的想法,这是正确的吗?
Is it correct that header files in C++ and abstract class/interface implementations in Java are both the same idea?
我对c++有点熟悉,我知道对于几乎每个头文件,我都必须创建一个源文件来配合它。
现在我正在研究java接口和实现,它看起来是一样的。首先,您只需在一个类中命名变量和方法,然后在另一个类中定义它们。
c++和Java中的这些东西基本相同还是相似?
Java接口和c++头文件/实现文件是不同的概念。
c++有一个文本编译模型。因此,要在代码中使用某些东西(例如函数),编译器必须首先解析该函数的定义。通过在头文件中放入你想要使用的许多源文件中的内容,可以节省你重新编写函数定义的时间,因为你可以将相同的头文件包含在使用该头文件中的内容的许多源文件中。
c++中的函数可以通过编写函数名和参数来声明:
void PrintMessage(std::string text);
也可以通过编写方法体来定义
void PrintMessage(std::string text)
{
cout << text;
}
您只能在编译单元中定义一次函数(这是编译器在#includes被它们包含的文件的文本替换之后看到的所有文本)。但是,你可以多次声明一个函数,只要声明是相同的。您必须定义每个只调用一次的函数。这就是为什么每个。h文件都有一个。cpp文件。.cpp定义了在.h文件中声明的所有函数。.h文件被包含到所有使用函数的.cpp文件中,并被包含一次到定义函数的.cpp文件中。
Java在编译项目时查看项目中的所有文件,从而确定函数的定义在哪里。c++一次只编译一个。cpp文件,并且只查看#include的头文件。
Java接口相当于c++抽象基类。它本质上是一组方法的声明,包括它们接受的参数类型和它们返回值的类型。Java接口或c++抽象基类可以被实际定义(实现)这些方法的Java类或c++类继承。
在c++中,当您创建一个类时,通常(有例外)将方法声明放入头文件中,并将定义放入.cpp文件中。但是,在Java中,您只需要编写方法的定义,这些定义就相当于c++的定义和声明于一体。您可以将所有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++中以抽象类的形式存在。它与.hpp和.cpp文件的分割无关。接口定义了一组函数,这些函数可以被子类/实现覆盖
不,它们是完全不同的。
Java没有等价的"头文件":API/数据结构的声明和类的实现的分离根本不存在。如果你想引用一些第三方类,那么你需要.class
文件,这与你想要运行第三方类时需要的完全相同(注意它们通常存储在.jar
文件中,但这只是为了方便)。
c++与Java接口最接近的是纯虚类:即定义一组方法但不定义任何实现的类。就像在Java中一样,你必须为它们生成一些子类,让它们真正有用,这些子类将提供实现。
他们非常不同。
Java接口更像是c++中的纯抽象类,其中没有任何方法具有实现。它们作为与对象的契约,以保证方法可以被调用。
接口存在的关键原因是Java没有多重继承,这意味着一个类只能扩展一个超类。然而,一个类可以实现多个接口,因此您可以定义任意数量的操作,您可以通过任意数量的接口对一个类执行操作。不尽然。
首先,Java接口不能包含变量,只能包含常量和方法。
第二,Java接口应该只在必要的地方创建,也就是说,当你有一个由几个类实现的API,并且你希望能够编写统一处理它们的代码时。大多数Java类应该不应该有匹配的接口,并且大多数Java接口应该有两个或更多的实现类。
头文件大多包含我们可以在某处重用的代码,接口只是一个契约,事情应该如何实现这是不一样的
c++是老的,它是建立在更老的C之上的。在c++中,类实际上是C风格的struct
,带有指向虚函数表的指针,其中包含指向类中每个函数的起始地址的指针。
放在头文件中的是类的定义,即结构体。在我们的实现中放入的是虚值表将指向的函数。这就是为什么需要在另一个文件中包含类的定义("头文件")才能使用它的原因。这也是为什么通常将类的定义放在单独的文件(.hpp)中。严格来说,你不必这样做,但如果你不这样做,在其他课程中使用这个类就会很困难。但是你也可以把你所有的代码放在一个大的文本文件中。
c++编译器将独立处理每个文件,扩展所有的#include宏,在每个.cpp文件中包含它们的定义。它还会将所有函数调用转换为虚值表表示法,即
someInstance-> someemethod()变成(someInstance->VTABLE[0]),假设someemethod()是someInstance类定义中声明的第一个。
编译器然后创建目标文件(所谓的翻译单元),并在内存布局中放置所有.cpp文件中实现的所有函数的结果机器码,并为所有虚表中的所有指针提供重定位表。链接器随后将重定位表中的符号替换为函数的实际内存地址。
长话短说,c++看起来是出于遗留目的(事实上C不是面向对象的)。Java从一开始就是面向对象的,这意味着接口是你可以使用的东西,与c++相反,c++的类定义是你必须拥有的东西(记住,结构和虚表),而且你必须以某种方式包括在你想要使用那个类的每个。cpp文件中。
- 在实现文件中使用头文件的通用 lambda
- 如何使用命令提示符、记事本和 MinGW 使用主文件、头文件和实现文件编译C++程序?
- 类中的数组变量C++导致"was not declared in this scope"实现文件的一个函数中错误,但在构造函数中不会导致错误
- 在实现文件中使用模板参数声明方法
- 模板实现文件中的匿名命名空间
- 创建单独的实现文件和头文件
- 当我从头文件和实现文件调用我的函数到我的主文件时,我没有得到任何输出
- 在实现文件中,我们应该更喜欢"using namespace"指令还是将实现包装在命名空间 { } 中?
- 包含适当的标头时,实现文件中的多个定义出错
- 如何在结构中实现文件读取和创建
- 在头文件和实现文件中创建模板模板函数
- C++头/实现文件中的默认和重载构造函数?
- 如何在C++实现文件中实例化类?
- 实现文件只能识别其他类的远期声明
- C++ 将字符串值传递到实现文件时出现问题
- 创建头文件和实现文件时出现问题
- C 从实现文件中访问私有静态成员
- Pimpl习惯用法、单独的接口/实现文件和多个虚拟继承.如何
- 没有实现文件(.cpp)的派生类
- 在标题或实现文件中定义常数的优点