类的多态性的概念
多态性(polymorphism)是面向对象程序设计的一个重要特征。利用多态性可以设计和实现一个易于扩展的系统。
在C++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性的:向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。
在C++程序设计中,在不同的类中定义了其响应消息的方法,那么使用这些类时,不必考虑它们是什么类型,只要发布消息即可。从系统实现的角度看,多态性分为两类:静态多态性和动态多态性。
前边学过的函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能决定调用的是哪个函数,因此静态多态性又称编译时的多态性。
静态多态性是通过函数的重载实现的(运算符重载实质上也是函数重载)。
动态多态性是在程序运行过程中才动态地确定操作所针对的对象。它又称运行时的多态性。
动态多态性是通过虚函数(virtual function)实现的。
有关静态多态性的应用已经介绍过了,这里主要介绍动态多态性和虚函数。
要研究的问题是:当一个基类被继承为不同的派生类时,各派生类可以使用与基类成员相同的成员名,如果在运行时用同一个成员名调用类对象的成员,会调用哪个对象的成员?也就是说,通过继承而产生了相关的不同的派生类,与基类成员同名的成员在不同的派生类中有不同的含义。也可以说,多态性是“一个接口,多种方法”。 下面是一个承上启下的例子。一方面它是有关继承和运算符重载内容的综合应用的例子,通过这个例子可以进一步融会贯通前面所学的内容,另一方面又是作为讨论多态性的一个基础用例。 例12.1 先建立一个Point(点)类,包含数据成员x,y(坐标点)。以它为基类,派生出一个Circle(圆)类,增加数据成员r(半径),再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类,再增加数据成员h(高)。要求编写程序,重载运算符“<<”和“>>”,使之能用于输出以上类对象。 对于一个比较大的程序,应当分成若干步骤进行。先声明基类,再声明派生类,逐级进行,分步调试。声明基类Point类可写出声明基类Point的部分如下: #include //声明类Point class Point { public: Point(float x=0,float y=0);//有默认参数的构造函数 void setPoint(float ,float);//设置坐标值 float getX( )const {return x;}//读x坐标 float getY( )const {return y;}//读y坐标 friend ostream & operator <<(ostream &,const Point &);//重载运算符“<<” protected ://受保护成员 float x, y; }; //下面定义Point类的成员函数 Point::Point(float a,float b) //Point的构造函数 {x=a;y=b;} //对x,y初始化 void Point::setPoint(float a,float b) //设置x和y的坐标值 {x=a;y=b;} //为x,y赋新值 ostream & operator <<(ostream &output, const Point &p){output<<″[″<display( );”可以调用不同派生层次中的display函数,只需在调用前给指针变量pt赋以不同的值(使之指向不同的类对象)即可。C++中的虚函数就是用来解决这个问题的。 虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。 请分析例12.2。这个例子开始时没有使用虚函数,然后再讨论使用虚函数的情况。 例12.2 基类与派生类中有同名函数。在下面的程序中Student是基类,Graduate是派生类,它们都有display这个同名的函数。 #include #include using namespace std; //声明基类Student class Student { public:Student(int, string,float);//声明构造函数void display( );//声明输出函数 protected ://受保护成员,派生类可以访问 int num; string name; float score; }; //Student类成员函数的实现 Student::Student(int n, string nam,float s)//定义构造函数{num=n;name=nam;score=s;} void Student::display( )//定义输出函数{cout<<″num:″<
posted on
2013-08-27 19:12
you Richer
阅读(812)
评论(0)
收藏
举报