多态的作用:继承是子类使用父类的方法,而多态则是父类使用子类的方法。
在C++中,多态有两种,一种是函数重载,一种是虚函数。函数重载发生在编译的时候,它的函数参数是不一样的。而虚函数是发生在运行的时候,它的函数原型是一样的,依靠的是指针的指向。
有一篇非常好的文章介绍多态与虚函数。发一个链接在这里。
http://blog.youkuaiyun.com/augusdi/article/details/38271009
这么一大堆名词,实际上就围绕一件事展开,就是多态,其他三个名词都是为实现C++的多态机制而提出的一些规则,下面分两部分介绍,第一部分介绍【多态】,第二部分介绍【虚函数,纯虚函数,抽象类】
一 、【多态】
多态的概念 :关于多态,好几种说法,好的坏的都有,分别说一下:
1、指同一个函数的多种形态。
个人认为这是一种高手中的高手喜欢的说法,对于一般开发人员是一种差的不能再差的概念,简直是对人的误导,然人很容易就靠到函数重载上了。
以下是个人认为解释的比较好的两种说法,意思大体相同:
2、多态是具有表现多种形态的能力的特征,在OO中是指,语言具有根据对象的类型以不同方式处理之,特别是重载方法和继承类这种形式的能力。
这种说法有点绕,仔细想想,这才是C++要告诉我们的。
3、多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function)实现的。
这种说法看来是又易懂,又全面的一种,尤其是最后一句,直接点出了虚函数与多态性的关系,如果你还是不太懂,没关系,再把3读两遍,有个印象,往后看吧。
二、【虚函数,纯虚函数,抽象类】
多态才说了个概念,有什么用还没说就进入第二部分了?看看概念3的最后一句,虚函数就是为多态而生的,多态的作用的介绍和虚函数简直关系太大了,就放一起说吧。
多态的作用:继承是子类使用父类的方法,而多态则是父类使用子类的方法。这是一句大白话,多态从用法上就是要用父类(确切的说是父类的对象名)去调用子类的方法,例如:
【例一】
- class A {
- public:
- A() {}
- (virtual) void print() {
- cout << "This is A." << endl;
- }
- };
- class B : public A {
- public:
- B() {}
- void print() {
- cout << "This is B." << endl;
- }
- };
- int main(int argc, char* argv[]) {
- B b;
- A a; a = b;a.print;---------------------------------------- make1
- // A &a = b; a->print();----------------------------------make2
- //A *a = new B();a->print();--------------------------------make3
- return 0;
- }
这将显示:
This is B.
如果把virtual去掉,将显示:
This is A.
(make1,2,3分别是对应兼容规则(后面介绍)的三种方式,调用结果是一样的)
加上virtual 多态了,B中的print被调用了,也就是可以实现父类使用子类的方法。
对多态的作用有一个初步的认识了之后,再提出更官方,也是更准确的对多态作用的描述:
多态性使得能够利用同一类(基类)类型的指针来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作。把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(也就是可以调用子对象中对父对象的相关函数的改进方法)。
那么上面例子中为什么去掉virtual就调用的不是B中的方法了呢,明明把B的对象赋给指针a了啊,是因为C++定义了一组对象赋值的兼容规则,就是指在公有派生的情况下,对于某些场合,一个派生类的对象可以作为基类对象来使用,具体来说,就是下面三种情形:
Class A ;
class B:public A
1. 派生的对象可以赋给基类的对象
A a;
B b;
a = b;
2. 派生的对象可以初始化基类的引用