第五章 面向对象的编程风格(面向对象编程概念)

5.1面向对象编程概念

 

面向对象编程概念的两项最主要的特质是:继承(inheritance)和多态(polymorphsim)。

 

前者使我们得以将一群相关的类组织起来,并让我们得以分享期间的共通数据和操作行为。
后者让我们在这些类上进行编程时,可以如同操纵单一个体,而非相互独立的类,并赋予我们更多的弹性来加入或移除任何特定的类。

 

    继承机制定义了父子(parent/child)关系。父类(parent)定义了所有子类(children)共通的公共接口(public interface)和私有实现(private implementation)。每个子类都可以增加或者覆盖(override)继承而来的东西,以实现自身独特的行为。例如:子类audiobook(有声书)除了从父亲book继承了作者和标题之外,还增加了播讲者以及耗用的卡代数、除此以外,它也有改写父类继承而来的check_out()函数

   

    在c++中,父类被成为基类(base class),子类被称为派生类(derived class)。

 

父类和子类的关系被称为继承体系(inheritance hierarchy).

 

例如在整个设计的复审会议中,我们可能说:“我希望能实现一个audiobook派生类。它会覆盖基类book的check_out()操作方法。不过,它还是沿用继承而来的book类的各笔数据,以及用来管理架位,作者,标题等信息的操作函数。


 “图书馆借阅系统”中的外借馆藏继承体系图见书   在面向对象应用程序中,我们会直接利用指向抽象基类的pointer或者reference来操作系统中的各个对象,而不是直接操作各个实际对象。这让我们得以在不跟动旧有程序的前提下,加入或者移除任何一个派生类,下面是个小例子:void loan_check_in(LibMat   &mat)
{
 //mat实际上代表某个派生对象(derived class object)
//诸如Book,Rentalbook,Magzines,等等
 mat.check_in();
 if(mat.is_late())
 mat.assess_fine();
 if(mat.waiting_list())
 mat.notify_available();
}
     我们的程序并不存在Libmat对象,只有Book,Rentalbook,Magzines等对象。这个函数实际上如何工作呢?举例来说,当我们通过mat调用check_in()时,究竟发生何事?此函数若要具有实际意义,每当loan_check_in()被调用,mat必定指向我们程序中的某个实际对象,此外,被调用的check_in()函数也势必被解析(resoved)为mat所代表的实际对象所拥有的那个check_in()函数。这便是整个进行过程。问题是它究竟如何工作的?
    

    面对对象编程风格的第二个独特的概念是多态(polymorphysm):让基类的pointer或reference十分透明地指向一个派生类对象。以上的loan_check_in()为例,mat总是指向代表LibMat的某个派生对象。但究竟是哪一个?答案是除非是程序执行的当下,否则无法确定。而且,loan_check_in()的每次执行结果都可能不同。


    动态绑定(dynamic binding)

是面向兑现改程序设计的第三个独特的概念、在非面向对象的编程风格中,我们写下这一行:
mat.check_in();

编译器在编译时就依据mat所属的类决定究竟执行哪一个check_in()函数。由于程序执行之前就已经解析出应该调用哪个函数,所以这种方式被称为静态绑定(static binding)
    但是面向对象编程风格中,编译器无法得知究竟哪一份check_in()函数会被调用。每次loan_check_in()执行时,仅能在执行过程中依据mat所指的实际对象来决定调用哪一个check_in()函数。这一解析操作会延迟至运行时(run_time)才进行。此即我们所谓的动态绑定。
 

   继承特性让我们得以定义一整群互有关联的类,并共享共同的接口,就像前述的各种图书馆藏。

  多态则让我们得以以一种与类型无关的方式来操纵这些对象。我们通过抽象基类的Pointer或者reference来操纵其共通接口,而实际执行起来的操作则需要等到运行时,依据pointer或reference所指的实际对象的类型才决定。是的!多态和动态绑定的特性,只有在使用Pointer或reference时才能发挥作用。


    如果图书馆决定不再借交互式书籍,我们只需将此类从继承体系类移除便可。loan_check_in()实现无需任何变动。同样道理,如果图书馆决定为特定的有声书收取额外的出租费用,我们可以做出另一个派生类audiorentalbook。loan_check_in()仍旧无需任何更改,如果图书馆决定借出笔记本电脑或者电视游戏机的设备和卡带,面对这种变动,我们的继承体系依然能够应付。

 

阅读更多
个人分类: essencial C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭