《面向对象程序设计多态.ppt》由会员分享,可在线阅读,更多相关《面向对象程序设计多态.ppt(16页珍藏版)》请在优知文库上搜索。
1、面向对象程序设计目录概念、实现及代码应用原理虚函数和迟后联编概念 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针或引用,来调用实现派生类中的方法。代码class A public: virtual void foo() cout This is A. endl; ; class B : public A public: void foo() cout This is B. foo(); return 0; ABpaPage 5目录应用原理虚函数和迟后联编概念、实现及代码Page 6应用 影片出租店案例 需要计算每位顾客的消费金额并打印报表。操作
2、者录入影片信息、租期时长,程序根据租赁时长和影片信息计算出费用。其中,影片分为:VCD、DVD。 由于光碟品质升级,影片类型后期需要添加BD(蓝光光碟)。 基于业务考虑,程序除了要计算费用,还要计算客户积分。Page 7实现class Diskpublic: virtual void caclRent(int days);class DVD:public Diskpublic: void caclRent( int days) int cost = days*3; cout该DVD的租期为days天,租金是:cost元。endl; ;/main.cppdouble caclRent(Disk
3、&disk,int days) disk.caclRent(days);int main() DVD dvd; Disk &disk = dvd; caclRent(disk,5); return 0;Page 8目录应用原理虚函数和迟后联编概念、实现及代码Page 9实现迟后联编的条件基于继承体系成员函数使用virtual修饰,定义为虚函数子类重写(override)父类的成员函数通过对象指针或者对象引用调用Page 10class Basepublic:virtual void foo()coutIn base class!endl;class Derived : public Basep
4、ublic:virtual void foo()coutIn derived class!foo();Page 11virtual有什么用 先看看这段代码:class Baseint data;public:void foo()/如果加上virtual,结果如何?coutIn base class!endl;int main()coutsizeof(Base)foo();Base* base = new Base();Base:foo(base);Base *base = new Base();base-foo();Base* base = new Base();base-vptr0();无v
5、irtual有virtualBase:foo()/.vptrint datavptr0NULLPage 13为什么要使用指针/引用 在单继承体系中,子类和父类共用一个虚函数表,其中子类中定义的虚函数添加在父类虚函数的后面。如前述案例中,子类对象内存空间如图: 对于对象,一但内存空间分配完毕,则虚函数表中函数指针所指向的函数就已经确定;而如果使用指针来访问,由于指针所指对象不同,因此实际使用的虚函数表也不同,相应的实际调用的函数也就不一样。Derived:foo()/.vptrint datavptr0NULLBase:foo()/.vptrint datavptr0NULL指针指向父类对象De
6、rived:foo()/.vptrint datavptr0NULL指针指向子类对象Page 14多态优缺点 优点: 提供了把接口与实现分开的一种方法; 提高了代码的组织性和可读性,更重要的是它使软件的可扩充性有了充分的提高; 是OOP的一个重要特征,提供了丰富的逻辑关系清晰的描述对象方法的手段,提高了软件功能和版本进化的设计维护能力。 缺点: 降低了程序执行的效率。Page 15与其它语言对比 Java Java中没有虚函数概念,或者说,Java中所有的成员函数都是虚函数,无需额外声明。 Java中的对象只能分配在堆(Heap)中,然后在栈中用引用(reference)指向之,因此Java中自然实现动态绑定。 C# C#中virtual和C+中类似。 C#中默认情况下不允许使用指针,对象内存分配上类似于Java C#中可以通过指定编译器选项,并使用unsafe关键字从而使用指针,但一般只用于编写native程序;对于托管程序,并不提倡使用指针。感谢您的关注!