多态分为静多态和动多态
1.静多态
函数重载,是一种多态现象,通过命名倾轧在编译阶段决定,故称为静多态。
2.动多态
动多态,不是在编译器阶段决定,而是在运行阶段决定,故称为动多态。动多态形成的条件如下:
1,父类中有虚函数。
2,子类override(覆写)父类中的虚函数。
3,将子类对象地址赋给父类的指针,并发生虚函数调用。(如果不用指针,用引用必须一开始必须绑定一个,而且一经确定,引用无法改)
3.虚函数
1.声明虚函数的方法
virtual void func(); //声明型关键字
2.override(覆写)
对比之前的重载和shadow
overload重载 同一作用域中,函数名相同,参数列表不同
shadow 发生在父子类中的同名成员
override 发生在父子类中,父类中函数含有 virtual 声明的函数
子类中,同参、同名、同返回的函数,构成覆写
PS:覆写的函数是否一定同父类的访问方式一样(public,private,protected),看子类的需求。
例子:
class Shape
{
public:
Shape(int xx,int yy)
:_x(xx),_y(yy) {}
virtual void draw();
protected:
int _x,_y;
};
void Shape::draw()
{
cout<<"draw from"<<"("<<_x<<","<<_y<<")"<<endl;
}
class Rect:public Shape
{
public:
Rect(int x,int y,int len,int wid)
:Shape(x,y),_len(len),_wid(wid)
{
}
virtual void draw()//覆写
{
cout<<"start from"<<"("<<_x<<","<<_y<<")";
cout<<" len="<<_len<<" wid="<<_wid<<endl;
}
private:
int _len,_wid;
};
class Circle:public Shape
{
public:
Circle(int x,int y ,int r)
:Shape(x,y),_radius(r){}
virtual void draw()//覆写
{
cout<<"start from"<<"("<<_x<<","<<_y<<")";
cout<<" radius="<<_radius<<endl;
}
private:
int _radius;
};
int main()
{
Circle c(1,2,3);
Shape *ps=&c; //这里不关心指针类型,主要看&c的类型
ps->draw();
ps=new Rect(1,2,3,4);
ps->draw();
return 0;
}
小结:
1,在基类中用virual声明成员函数为虚函数。类外实现虚函数时,不必再加virtual.
2,在派生类中重新定义此函数称为覆写,要求函数名,返值类型,函数参数个数及类型全部匹配。并根据派生类的需要重新定义函数体。
3,当一个成员函数被声明为虚函数后,其派生类中完全相同的函数(显示的写出)也为虚函数。可以在其前加virtual以示清晰。
4,定义一个指基类对象的指针,并使其指向其子类的对象,通过该指针调用虚函数,此时调用的就是指针变量指向对象的同名函数。
5,子类中的覆写的函数,可以为任意访问类型,依子类需求决定。