什么是多态性
向不同的对象发生同一消息,不同的对象在接收时会产生不同的行为。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
利用虚函数实现动态多态性
虚函数的作用
虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
静态关联与动态关联
静态关联:
函数重载和通过对象名调用的虚函数,在编译时即可确定其调用的虚函数属于哪一类,其过程称为静态关联,也称为早期关联。函数重载属于静态关联。
动态关联:
在运行阶段把虚函数和类对象绑定在一起的过程称为动态关联,这种多态性是动态的多态性,即运行阶段的多态性。
纯虚函数与抽象类
纯虚函数
纯虚函数是在声明虚函数时被“初始化”为0的函数。
一般形式:
virtual 函数类型 函数名(参数表列)=0;
纯虚函数没有函数体
最后的“=0”并不表示函数的返回值是0,它只起形式上的作用,告诉编译系统“这是纯虚函数”
这是一个声明语句,最后应加上“;”
抽象类
不用来定义对象而只作为一种基本类型用作继承的类,称为抽象类,通常称为抽象基类。
凡是包含纯虚函数的类都是抽象类。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的。抽象类的作用是做为一个类族的共同基类,或者说,为一个类族提供一个公共的接口。
应用实例
#include<iostream>
using namespace std;
class shape{
public:
virtual float area() const {return 0.0;}
virtual float volume() const {return 0.0;}
virtual void shapename() const =0;
};
----------------------------------------------------------
class point:public shape{
public:
point(float =0,float =0);
void setpoint (float,float);
float getX() const {return x;}
float getY() const {return y;}
virtual void shapename() const {cout<<"point:";}
friend ostream & operator<<(ostream &,const point &);
protected:
float x,y;
};
point::point(float a,float b){
x=a;y=b;
}
void point::setpoint(float a,float b){
x=a;y=b;
}
ostream & operator <<(ostream &output,const point &p){
output<<"["<<p.x<<","<<p.y<<"]";
return output;
}
----------------------------------------------------------
class circle::public point{
public:
circle(float x=0,float y=0,float r=0);
void setradius(float);
float gatradius() const;
virtual float area() const;
virtual void shapename() const{cout<<"circle:";}
friend ostream &operator <<(ostream &,const circle &);
protected:
float radius;
};
circle ::circle(float a,float b,float r):point(a,b),radius(r){
}
void circle::setradius(float r):radius(r){
}
float circle::getradius() const {return radius;}
float circle::area() const {return 3.14159*radius*radius;}
ostream & operator <<(ostream &output,const circle &c){
output<<"["<<c.x<<","<<c.y<<"],"<<"r="<<c.radius;
return output;
}
----------------------------------------------------------
class cylinder:public circle{
public:
cylinder (float x=0,float y=0,float r=0,float h=0);
void setheight(float);
virtual float area() const;
virtual float volume() const;
virtual void shapename() const{cont<<"cylinder:";}
friend ostream & operator <<(ostream&,const cylinder&);
protected:
float height;
};
cylinder::cylinder(float a,float b,float r,float h):circle(a,b,r),height(h){
}
void cylinder::setheight(float h){
height=h;
}
float cylinder::area() const{return 2*circle::area()+2*3.14159*radius*height;}
float cylinder::volume() const{return circle::area()*height;}
ostream & operator <<(ostream &output,const cylinder &cy){
output<<"["<<cy.x<<","<<cy.y<<"]"<<"r="<<c.radius<<"h="<<cy.height;
return output;
}
----------------------------------------------------------
int main(){
point point(3.2,4.5);
circle circle(2.4,1.2,5.6);
cylinder cylinder(3.5,6.4,5.2,10.5);
point.shapename();
cout<<point<<endl;
circle.shapename();
cout<<circle<<endl;
cylinder.shapename();
cout<<cylinder<<endl<<endl;
shape *pt;
pt=&point;
pt->shapename();
cout<<"x="<<point.getX()<<"y="<<point.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
pt=&circle;
pt->shapename();
cout<<"x="<<circle.getX()<<"y="<<circle.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
pt=&cylinder;
pt->shapename();
cout<<"x="<<cylinder.getX()<<"y="<<cylinder.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
return 0;
}