目录
一、什么是多态
多态的地位?多态(Polymorphism)是面向对象(Object-Oriented,OO)思想"三大特征"之一,其余两个分别是封装(Encapsulation)和继承(Inheritance)-- 可见多态的重要性。或者说,不懂得什么是多态就不能说懂得面向对象。
为什么要用多态?封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。
多态是一种机制、一种能力,而非某个关键字。按字面的意思就是多种形态的意思,可以说同一个函数具有多种形式,比如不同的返回值,参数,运行的内容等。
二、多态的种类
1、重载
重载指的是在同一个作用域内,两函数的函数名可以相同,但是参数不能完全相同,可以是参数类型不同或者是参数个数不同。重载比较简单不多讲了。
2、模版
将程序所处理的对象的类型参数化,使得一段程序可以用于处理多种不同类型的对象。模板就是C++支持参数化多态的工具。包括函数模版和类模板。
3、强制转换
当基类A指针调向派生类对象B时,想调用派生类B的函数Bfunc()时,可以用 dynamic_cast<B*>(p)->func();这种方式,强制转换进行调用。
class A {
public:
virtual void run() = 0;
};
void A::run(){
cout << "run()" << endl;
}
class B : public A {
public:
void run();
void func();
};
void B::run(){
cout << "run()" << endl;
}
void B::func(){
cout << "func()" << endl;
}
int main(){
A *p = new B();
dynamic_cast<B*>(p)->func(); // cast A* to B*
p->func();
}
4、虚函数和重写
在外部程序中定义一个指向基类对象的指针。根据赋值兼容准则(派生类对象是基类对象,反之不成立),该指针也可指向基类对象,如果该对象指针指向基类对象则调用基类的成员函数,如果该对象指针指向派生类对象则调用派生类的成员函数。当基类指针指向派生类对象时,若基类函数声明为虚函数而在派生类重写时,基类指针调用该函数则为派生类里实现的函数。
class Person
{
public:
void Walk(){printf("Person Walk()\n");}//取基类
virtual void Look() {printf("Person Look()\n");}//取派生类
virtual void Eat() {printf("Person Eat()\n");}//取派生类
virtual void See() final {printf("Person See()\n");}//final 防止被意外重写 取本类
};
class Man :public Person
{
public:
void Walk(){printf("Man Walk()\n");}
void Look() {printf("Man Look()\n");}
void Eat() override {printf("Man Eat()\n");}
//void See() {printf("Man See()\n");}//错误的,因为基类用了final
};
int main()
{
Person *p=new Man();
p->Walk();//取基类
p->Look();//取派生类
p->Eat();//取派生类
p->See();//同Eat但加了final 取基类
dynamic_cast<Man*>(p)->Walk();//取派生类
Man *k=(Man*)(p);k->Walk();//同上 取派生类
p->Person::Look();//取基类
return 0;
}
三、多态的分类
1、静态动态
这里指的是编译时就确定执行哪个同名函数(静态。也叫编译时的多态性),还是在执行的时候才能决定(动态,也叫运行时的多态)。
在这里静态多态就是重载,动态多态就是通过继承重写基类的虚函数来实现
2、面向对象的多态性
面向对象的多态性可以分为四类:重载多态、强制多态、包含多态和参数多态.
重载多态:普通函数及类的成员函数的重载,运算符重载
强制多态:将一个变元的类型加以变化,即类型强制转换(派生类中又定义了一个基类中没有的方法,可使用dynamic_cast将基类转为派生类对象)
包含多态:虚函数
参数多态:类模板.
3、面向对象的形式
其中「参数多态」和「包含多态」称为通用多态,「过载多态」和「强制多态」称为特定多态.
本博客是博主个人学习时的一些记录,个别文章加入了转载的源地址还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注者,如有侵权请与博主联系。
参考: