接口实现和继承实现.docx

上传人:夏** 文档编号:542613590 上传时间:2023-04-24 格式:DOCX 页数:13 大小:28.06KB
返回 下载 相关 举报
接口实现和继承实现.docx_第1页
第1页 / 共13页
接口实现和继承实现.docx_第2页
第2页 / 共13页
接口实现和继承实现.docx_第3页
第3页 / 共13页
接口实现和继承实现.docx_第4页
第4页 / 共13页
接口实现和继承实现.docx_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《接口实现和继承实现.docx》由会员分享,可在线阅读,更多相关《接口实现和继承实现.docx(13页珍藏版)》请在金锄头文库上搜索。

1、C+接口继承与实现继承接口继承与实现继承所谓接口继承,就是派生类只继承函数的接口,也就是声明;而实现继承,就是派生类同时继承函数的接口和实现。我们都很清楚C+中有几个基本的概念,虚函数、纯虚函数、非虚函数。虚函数:虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。MSDN虚函数用来表现基类和派生类的成员函数之间的一种关系.虚函数的定义在基类中进行,在需要定义为虚函数的成员函数的声明前冠以关键字virtual.基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义.在派生类中重新定义时

2、,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同.虚函数是重载的一种表现形式,是一种动态的重载方式.纯虚函数:纯虚函数在基类中没有定义,它们被初始化为0。任何用纯虚函数派生的类,都要自己提供该函数的具体实现。定义纯虚函数virtual void fun(void) = 0;非虚函数:一般成员函数,无virtual关键字修饰。至于为什么要定义这些函数,我们可以将虚函数、纯虚函数和非虚函数的功能与接口继承与实现继承联系起来:声明一个纯虚函数(pure virtual)的目的是为了让派生类只继承函数接口,也就是上面说的接口继承。纯虚函数一般是在不方

3、便具体实现此函数的情况下使用。也就是说基类无法为继承类规定一个统一的缺省操作,但继承类又必须含有这个函数接口,并对其分别实现。但是,在C+中,我们是可以为纯虚函数提供定义的,只不过这种定义对继承类来说没有特定的意义。因为继承类仍然要根据各自需要实现函数。通俗说,纯虚函数就是要求其继承类必须含有该函数接口,并对其进行实现。是对继承类的一种接口实现要求,但并不提供缺省操作,各个继承类必须分别实现自己的操作。声明非纯虚函数(impure virtual)的目的是让继承类继承该函数的接口和缺省实现。与纯虚函数唯一的不同就是其为继承类提供了缺省操作,继承类可以不实现自己的操作而采用基类提供的默认操作。声

4、明非虚函数(non-virtual)的目的是为了令继承类继承函数接口及一份强制性实现。相对于虚函数来说,非虚函数对继承类要求的更为严格,继承类不仅要继承函数接口,而且也要继承函数实现。也就是为继承类定义了一种行为。总结:纯虚函数:要求继承类必须含有某个接口,并对接口函数实现。虚函数:继承类必须含有某个接口,可以自己实现,也可以不实现,而采用基类定义的缺省实现。非虚函数:继承类必须含有某个接口,必须使用基类的实现。C+箴言:接口继承和实现继承(public) inheritance 这个表面上简单易懂的观念,一旦被近距离审视,就会被证明是由两个相互独立的部分组成的:inheritance of

5、function interfaces(函数接口的继承)和 inheritance of function implementations(函数实现的继承)。这两种 inheritance 之间的差异正好符合本书 Introduction 中论述的 function declarations(函数声明)和 function definitions(函数定义)之间的差异。作为一个 class 的设计者,有的时候你想要 derived classes 只继承一个 member function 的 interface (declaration)。有的时候你想要 derived classes 既继

6、承 interface(接口)也继承 implementation(实现),但你要允许它们替换他们继承到的 implementation。还有的时候你想要 derived classes 继承一个函数的 interface(接口)和 implementation(实现),而不允许它们替换任何东西。为了更好地感觉这些选择之间的不同之处,考虑一个在图形应用程序中表示几何图形的 class hierarchy(类继承体系):class Shape public:virtual void draw() const = 0;virtual void error(const std:string& msg

7、);int objectID() const;.;class Rectangle: public Shape . ;class Ellipse: public Shape . ;Shape 是一个 abstract class(抽象类),它的 pure virtual function(纯虚拟函数)表明了这一点。作为结果,客户不能创建 Shape class 的实例,只能创建从它继承的 classes 的实例。但是,Shape 对所有从它(公有)继承的类施加了非常强大的影响,因为成员函数 interfaces are always inherited。就像 Item 32 解释的,public

8、 inheritance 意味着 is-a,所以对一个 base class 来说成立的任何东西,对于它的 derived classes 也必须成立。因此,如果一个函数适用于一个 class,它也一定适用于它的 derived classes。Shape class 中声明了三个函数。第一个,draw,在一个明确的显示设备上画出当前对象。第二个,error,如果 member functions 需要报告一个错误,就调用它。第三个,objectID,返回当前对象的唯一整型标识符。每一个函数都用不同的方式声明:draw 是一个 pure virtual function(纯虚拟函数);erro

9、r 是一个 simple (impure?) virtual function(简单虚拟函数);而 objectID 是一个 non-virtual function(非虚拟函数)。这些不同的声明暗示了什么呢?考虑第一个 pure virtual function(纯虚拟函数)draw:class Shape public:virtual void draw() const = 0;.;pure virtual functions(纯虚拟函数)的两个最显著的特性是它们必须被任何继承它们的具体类重新声明,和抽象类中一般没有它们的定义。把这两个特性加在一起,你应该认识到。声明一个 pure vir

10、tual function(纯虚拟函数)的目的是使 derived classes 继承一个函数 interface only。这就使 Shape:draw function 具有了完整的意义,因为它要求所有的 Shape 对象必须能够画出来是合情合理的,但是 Shape class 本身不能为这个函数提供一个合乎情理的缺省的实现。例如,画一个椭圆的算法和画一个矩形的算法是非常不同的,Shape:draw 的声明告诉具体 derived classes 的设计者:“你必须提供一个 draw function,但是我对于你如何实现它不发表意见。”顺便提一句,为一个 pure virtual fu

11、nction(纯虚拟函数)提供一个定义是有可能的。也就是说,你可以为 Shape:draw 提供一个实现,而 C+ 也不会抱怨什么,但是调用它的唯一方法是用 class name 限定修饰这个调用:Shape *ps = new Shape; / error! Shape is abstractShape *ps1 = new Rectangle; / fineps1-draw(); / calls Rectangle:drawShape *ps2 = new Ellipse; / fineps2-draw(); / calls Ellipse:drawps1-Shape:draw(); /

12、calls Shape:drawps2-Shape:draw(); / calls Shape:draw除了帮助你在鸡尾酒会上给同行程序员留下印象外,这个特性通常没什么用处,然而,就像下面你将看到的,它能用来作为一个“为 simple (impure) virtual functions 提供一个 safer-than-usual 的实现”的机制。simple virtual functions 背后的故事和 pure virtuals 有一点不同。derived classes 照常还是继承函数的 interface,但是 simple virtual functions 提供了一个可以被

13、derived classes 替换的实现。如果你为此考虑一阵儿,你就会认识到声明一个 simple virtual function 的目的是让 derived classes 继承一个函数 interface as well as a default implementation。考虑 Shape:error 的情况:class Shape public:virtual void error(const std:string& msg);.;interface 要求每一个 class 必须支持一个在遭遇到错误时被调用的函数,但是每一个 class 可以自由地用它觉得合适的任何方法处理错误。

14、如果一个 class 不需要做什么特别的事情,它可以仅仅求助于 Shape class 中提供的错误处理的缺省版本。也就是说,Shape:error 的声明告诉 derived classes 的设计者:“你应该支持一个 error function,但如果你不想自己写,你可以求助 Shape class 中的缺省版本。”结果是:允许 simple virtual functions 既指定一个函数接口又指定一个缺省实现是危险的。来看一下为什么,考虑一个 XYZ 航空公司的飞机的 hierarchy(继承体系)。XYZ 只有两种飞机,Model A 和 Model B,它们都严格地按照同样的方法飞行。于是,XYZ 设计如下 hierarchy(继承体系):class Airport . ; / represents airportsclass Airplane public:virtual void fly(const Airport& destination);.;void Airplane:fly(const Airport& destination)default code for flying an airplane to the given destinationclass ModelA: public

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号