抽象类/接口C++

Abstract Class/Interface C++

本文关键字:C++ 接口 抽象类      更新时间:2023-10-16

我在理解抽象类/接口时遇到了一些困难,我想知道是否有人能帮助我理解。

我的理解是,接口是一种定义对象功能(如何使用它)的方法,而不定义其实现。

例如,以电视为例。

许多制造商生产电视。如果我们要为电视定义一个接口,它可能有以下方法:

ChangeChannel,PowerOn,断电,RaiseVolume等

因此,接口是人机接口(按钮、旋钮等),实现是我们正在接口的"黑盒"内部。

因此,如果我们编写了一些继承自TV的类,如PhilipsTV、SonyTV等,它们定义了自己在TV中定义的方法的实现,那么这些特定的制造商TV对象将覆盖TV接口方法,并提供实现。

因此,如果我们想将电视对象传递给一个函数,但直到运行时才知道是哪个特定的制造商制造了电视,那么我们可以使用这样的函数:

void doSomethingWithTV(TV telly){
    telly.ChangeVolume(10);
}

并这样称呼它:

void main()
{
    SonyTV t = new SonyTV;
    doSomethingWithTV(t);
}

doSomethingWithTV的内部会知道电视有什么方法,因为它是从电视接口继承的,但我们可能会在运行时传入SonyTV或PhilipsTV等,它们将被同等对待。

不幸的是,正如我的编译器所说,我很难将接口类型作为参数传递:

无法将参数"telly"声明为抽象类型"TV",因为以下虚拟函数在"TV"中是纯函数:

虚拟无效TV::changeVolume(int)

请有人告诉我,我是否正确理解了"界面"一词,如果是,我应该如何指导我的研究,以便我能够学习必要的技能,从而能够实现如上所述的模式。

事先谢谢你,里克。

"不幸的是,正如我的编译器所说,我很难将接口类型作为参数传递:…"

您无法按值传递抽象接口,因此您更改

void doSomethingWithTV(TV telly){
    telly.ChangeVolume(10);
}

接收像这个一样的参考或指针参数

void doSomethingWithTV(TV& telly);

void doSomethingWithTV(TV* telly);

by value参数要求您具有TV的实例。

是的,没关系,除了两个观察结果:

  • main必须返回int,而不是void
  • C++不是Java。不能按值传递对象的接口类型,并期望多态性起作用。您要做的是将一个新的TV对象传递到函数中,但这无法工作,因为接口无法实例化。如果您转而传递引用TV&const TV&或指针TV*,那么这将是原始对象的句柄,并且当您使用句柄时,多态性可能会占据上风

这两点都在你的C++书中解释过,所以继续读到最后。

是的,您对什么是接口的理解非常清楚。

但是:

必须将接口类型(此处为Tv)与指针一起使用。

因此,在你的例子中,它将是:

void doSomethingWithTV(TV* telly){
    telly->ChangeVolume(10);
}

void main()
{
    TV* t = new SonyTV;
    doSomethingWithTV(t);
 }

接口是用来传递一种契约的:如果你想从我那里继承,你必须实现我包含的所有纯虚拟函数。它不是要实例化的。

正如您所说,要调用的函数将在运行时确定,因此编译器在编译时不知道要调用哪些代码。

这是因为您的TV类具有纯虚拟函数。不能用纯虚拟函数实例化类。任何具有纯虚拟函数的类都是抽象类。这些类不能单独存在,它们需要由例如SonyTV派生。如果这个SonyTV定义了纯虚拟函数,那么它就可以工作了。

您正在执行SomethingWithTV()请求TV,您是编译器错误,因为此函数永远无法接收TV。但是,它可以接收对TV的引用或从TV派生的类。

更多信息:https://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classeshttps://en.wikipedia.org/wiki/Virtual_function