上周去面试,彻底被基础知识搞懵逼了,感觉明明是自己做过的项目也变成别人的了。
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
意义:
把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
赋值之后,父类型的引用就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。
附加:
当我们的父类有纯虚函数时,这个父类不能被创建对象,但是他的子类实现这个纯虚函数函数了,可以被用来创建对象,而且我们可以把子类的指针强制转换成父类指针,然后用父类指针去调用。
拥有纯虚函数的类同样适用多态法则。
#include<iostream>
using namespace std;
class Father{
public:
virtual void ptlog(){
printf("I'm father \n");
}
};
class BChild:public Father{
public:
virtual void ptlog(){
printf("I'm big sun\n");
}
virtual void childOwn(){
printf("This is the only child fun \n");
}
};
class LChild:public Father{
public:
virtual void ptlog(){
printf("I'm little sun\n");
}
void childOwn(){
printf("This is the only child fun \n");
}
};
int main(int argc, char*argv[])
{
BChild *bchild = new BChild();
Father *castFather = (Father *)bchild;
castFather->ptlog();
LChild *lchild = new LChild();
castFather = (Father *)lchild;
castFather->ptlog();
Father *father = new Father();
//err
//father->childOwn();
BChild *castBChild = (BChild *)father;
//setment fault
//castBChild->childOwn();
return 0;
}
运行结果:
I'm big sun
I'm little sun
进阶理解:
#include <iostream>
#define NOT_DEFINE_STU 1
class Father{
//c++默认private,如果不写public,对外不可见
public:
virtual void paramore(int para1){
printf("father paramore pt, %d\n", para1);
}
virtual void paramore(int para1, int para2 ,int para3){
printf("father paramore pt, %d %d %d\n", para1, para2, para3);
}
virtual void childNotHave(){
printf("father pt, child not has this mothed !\n");
}
};
class Child:public Father{
//因为父类没有对应的方法(父类的方法虽然同名但是不同参),
//所以这里会认为是一个全新的方法,不加public会被认为是私有
public: //这个public必须写,有意思!
virtual void paramore(int para1, int para2 ,int para3){
printf("child paramore 3 para pt, %d %d %d\n", para1, para2, para3);
}
#if NOT_DEFINE_STU
//因为父类没有对应的方法,且父类定义了virtual 的同名不同参方法,警告:
//warning: 'Child::paramore' hides overloaded virtual function [-Woverloaded-virtual]
//note: hidden overloaded virtual function 'Father::paramore' declared here: different number of parameters (1 vs 2)
//总结性的讲,它违背了多态设计原理
public:
virtual void paramore(int para1, int para2){
printf("child paramore 2 para pt, para:=%d %d\n", para1, para2);
}
#endif
};
int main(){
Child *child = new Child();
Father *father = (Father *)child;
//如果子类没有重写父类的方法,遵循标准的继承原则。
father->childNotHave();
child->childNotHave();
//多态的意义!!!
father->paramore(1, 2, 3);
//一旦子类重写父类的方法,就会产生覆盖,调用方法时会根据对象查找各自的映射表。
//正确,父类可以找到
father->paramore(1);
//出错,子类没有这个方法,找不到
// child->paramore(1);
#if NOT_DEFINE_STU
//只能用在子类
child->paramore(1, 2);
//提示找不到方法
//father->paramore(1, 2);
#endif
return 0;
}
//1
//如果子类没有重写父类的方法,那么它适用于c++的标准继承法则。
//2.1
//如果子类重写了父类的方法,我们认为只是继承而不是衍生,
//所以对于两个参数的情况,因为父类没有,虽然我们可以在子类中这么写,但是编译器提出警告
//因为它违背了多态的设计原理
//2.2
//如果有的方法,父类定义了,但是子类又没有实现,比如我们只有一个参数的情况
//这时,我们会认为在子类中不需要这个方法(面向对象的设计理念)
//如果定义了一个子类对象,又要使用这个方法时,要先强制转换成父类指针。
运行结果:
father pt, child not has this mothed !
father pt, child not has this mothed !
child paramore 3 para pt, 1 2 3
father paramore pt, 1
child paramore 2 para pt, para:=1 2