我有几天困扰我的问题。
抽象类是一种特殊类型的类,我们不能实例化,对吧?(通过给至少一个方法声明一个“= 0”来表示/指定,这看起来像是事后的想法)。
抽象类机制为 C++ 带来了哪些“普通”基类无法实现的额外好处?
我有几天困扰我的问题。
抽象类是一种特殊类型的类,我们不能实例化,对吧?(通过给至少一个方法声明一个“= 0”来表示/指定,这看起来像是事后的想法)。
抽象类机制为 C++ 带来了哪些“普通”基类无法实现的额外好处?
这是在类设计者和该类的用户之间强制签订合同的一种方式。如果我们希望从抽象类创建一个具体类(可以实例化的类),我们必须为基类的每个抽象成员函数声明和定义一个匹配的成员函数。
如前所述,它是一种定义派生类必须遵守的接口的方法。他们的Vehicle
抽象类的例子非常恰当:Vehicle
在现实生活中你永远不会只有一个,你会有福特探索者或丰田普锐斯,但它们都符合(为了论证)一组基本功能这是一个Vehicle
可能的定义。但是,你不能只是去Vehicle
经销商那里开车Vehicle
。因此,您永远不会希望能够Vehicle
在您真正需要专门的派生对象的地方构造和使用基础对象。
这提供了在 C++ 中定义没有任何默认实现的接口的最佳方式。
C++ 没有 C# 的interface
概念。
它相当于Java变成了“接口”。基本上,这意味着该类本身不可用 - 您需要覆盖所有纯方法。
一个例子是 MFC 的 CView 类,它有一个纯 OnDraw 方法 - 基本的 CView 不做任何事情,因此毫无用处。您必须覆盖 OnDraw。
(顺便说一句 - 仍然可以为纯方法提供实现,子类实现可以回退到它,但它们仍然必须提供自己的覆盖。)
它们在类层次结构设计中用作基类。
抽象类用于为所有派生类定义一个干净的接口。
在设计阶段,抽象类定义一个接口,每个规范和派生类相应地实现所需的功能。
同样使用抽象类而不是“普通”类有助于将实现细节与接口分离。
一个具体的类实现了一个接口,但抽象类定义了它。您可以在设计中使用具体类作为基类,但抽象类并不意味着直接在代码中使用并且不能被实例化。它们用作原型。
正如您所说,通过使用“普通”类,您必须为所有方法定义一个实现。
不要在课堂上考虑它。
看方法,想想在默认情况下应该怎么做:
virtual std::string getName() const = 0;
这种方法的正确实现是什么?没有比我能想到的了。
通过将其标记为“纯虚拟”,您可以确保如果用户获得了从您的接口派生的类的实例,那么此方法将具有合理的行为。
唯一的另一种方法是使用throw NotImplemented("getName");
正文,但是您会在运行时发现问题,而不是在编译时发现问题,这不是很好:)