- ♂️ 作者:海码007
- 专栏:C++专栏
- 标题:C++ 抽象类和接口 详解
- ❣️ 寄语:书到用时方恨少,事非经过不知难!
- 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正
随着编程的深入,总是会听到不少抽象类,接口等词汇。但是其实很多有都在混淆概念,甚至是乱用这些定义。接下来就和我一起探讨一下C++中的抽象类和接口的区别,以及拓展一下 C++ 和 Java 的区别。
在C++中,抽象类(Abstract Class)
是包含至少一个
纯虚函数的类。抽象类不能被实例化
,只能被用作其他类的基类。纯虚函数
是一种在基类中声明但没有提供实际实现的虚函数,它的存在要求任何继承自这个基类的派生类都必须提供实际的实现(如果不实现,那基类仍然是抽象类)。这样的设计允许抽象类提供一个接口,而具体的实现则由派生类完成。
在C++中,定义一个抽象类的典型方式如下:
class AbstractClass {
public:
// 纯虚函数,使得AbstractClass成为抽象类
virtual void pureVirtualFunction() = 0;
// 虚析构函数(防止派生类析构时,不调用派生类的析构函数)
virtual ~AbstractClass() {}
// 普通成员函数
void concreteFunction() {
// 可以包含具体实现
// 但通常抽象类中也包含一些纯虚函数,以强制派生类提供实现
}
// 普通成员变量
int data;
};
在这个例子中,pureVirtualFunction
是一个纯虚函数,因此AbstractClass
就成为了抽象类。由于抽象类不能被实例化,你不能创建AbstractClass
的对象。它主要用于作为其他类的基类,要求派生类必须提供纯虚函数的实际实现。
具体的派生类可以这样实现:
class ConcreteClass : public AbstractClass {
public:
// 实现纯虚函数
void pureVirtualFunction() override {
// 具体的实现
}
};
注意,在派生类中必须提供对抽象类中纯虚函数的实现,否则派生类也会变成抽象类,无法被实例化。
在C++中接口就是一种特殊的抽象类
,接口中只包括纯虚函数。
在C++中,与一些其他编程语言(如Java和C#)不同,C++没有显式的接口关键字。然而,C++中可以通过抽象类和纯虚函数来实现接口的概念。
在C++中,接口通常是通过抽象类来定义的,该抽象类包含纯虚函数(没有实现),而派生类则负责提供这些纯虚函数的具体实现。这种方式类似于其他语言中的接口定义。
下面是一个使用抽象类和纯虚函数实现接口的简单示例:
#include
// 定义接口(抽象类)
class Interface {
public:
// 纯虚函数,相当于接口中的方法声明
virtual void doSomething() = 0;
};
// 不能在接口中包含普通成员函数
// 下面的代码会导致编译错误
/*
class Interface {
public:
virtual void doSomething() = 0;
void commonFunction() {
std::cout << "Common function in Interface." << std::endl;
}
};
*/
// 实现接口的具体类
class ConcreteClass : public Interface {
public:
// 提供接口中纯虚函数的具体实现
void doSomething() override {
std::cout << "Doing something in ConcreteClass." << std::endl;
}
};
int main() {
// 通过接口指针调用实现类的方法
Interface* obj = new ConcreteClass();
obj->doSomething();
delete obj;
return 0;
}
Java和C++在接口(interface)方面存在一些显著的区别。了解这些区别对于使用这两种语言进行编程是很重要的。以下是主要的区别点:
定义和用途:
实现方法:
interface
关键字来实现接口,并且必须实现接口中的所有方法。默认方法:
属性:
public static final
的。多重继承和菱形问题(Diamond Problem):
这些差异反映了Java和C++设计哲学的不同:Java更注重简洁和安全,而C++提供了更高的灵活性和控制权,但也带来了更复杂的语言特性和潜在的错误风险。
// 定义一个接口
interface Vehicle {
void drive();
int getNumberOfWheels();
}
// 一个类实现接口
class Car implements Vehicle {
public void drive() {
// 实现drive方法的具体逻辑
}
public int getNumberOfWheels() {
// 返回轮子数量
return 4;
}
}