多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。其实我看到过一句话:调用同名函数却会因上下文的不同而有不同的实现。我觉得这样更加贴切,还加入了多态三要素:(1)相同函数名 (2)依据上下文 (3)实现却不同;
多态是c++的特征之一
1 class Animal 2 { 3 public: 4 void sleep(void) 5 { 6 cout<<"animal 动物在睡觉"<<endl; 7 } 8 }; 9 10 class Cat:public Animal 11 { 12 public: 13 void sleep(void) 14 { 15 cout<<"Cat 猫在睡觉!! 喵喵"<<endl; 16 } 17 }; 18 void test01() 19 { 20 //用基类(指针或引用) 保存 子类对象(向上转换) 21 Animal *p = new Cat; 22 p->sleep();//调用的是基类的sleep 23 24 Cat cat; 25 Animal &ob = cat; 26 ob.sleep();//调用的是基类的sleep 27 }
总结:基类指针、引用 只能访问 子类对象中 基类部分 数据
3、使用基类指针、引用 访问 子类对象中的成员方法(虚函数)
使用virtual修饰成员函数 该成员函数就是虚函数。
1 class Animal 2 { 3 public: 4 //虚函数 5 virtual void sleep(void) 6 { 7 cout<<"animal 动物在睡觉"<<endl; 8 } 9 };
1 class Animal 2 { 3 public: 4 //虚函数 本质 是一个函数指针变量 5 virtual void sleep(void) 6 { 7 cout<<"animal 动物在睡觉"<<endl; 8 } 9 }; 10 void test01() 11 { 12 //如果 Animal没有涉及到继承 函数指针变量 就指向自身sleep 13 Animal ob; 14 ob.sleep(); 15 }
4、拥有虚函数的类 涉及得到继承 2-2
1 class Animal 2 { 3 public: 4 //虚函数 本质 是一个函数指针变量 5 virtual void sleep(void) 6 { 7 cout<<"animal 动物在睡觉"<<endl; 8 } 9 }; 10 class Cat:public Animal 11 { 12 public: 13 virtual void sleep(void) 14 { 15 cout<<"猫在睡觉!!喵喵"<<endl; 16 } 17 };
虚函数的定义要遵循以下重要规则:
1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的。
2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。
3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。
4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。
5.构造函数不能是虚函数,因为构造的时候,对象还是一片位定型的空间,只有构造完成后,对象才是具体类的实例。
6.析构函数可以是虚函数,而且通常声名为虚函数。
同时需要了解多态的特性的virtual修饰,不单单对基类和派生类的普通成员 函数有必要,而且对于基类和派生类的析构函数同样重要