之前以为自己的博客记录了对这方面的知识,但是发现好像真没有,于是今天抽空来记录下我的我对继承和多态的理解。继承这块我不想记录的太多,大致解释一下就行,因为比较普及,大家应该都明白,也不需要详细解释,重点记录一下多态的理解。
C++的继承可以说是最初始的继承,后面的高级语言java和python之类的继承都是源自C++的继承。所谓的继承就是说一个类里面有多个函数方法,然后另外一个类继承了此类,新的类啥也不用实现就可以使用被继承类里面实现的方法。
在一篇文章我看到过有人这样说多态:就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。 举个栗子:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。此时我们就可以在脑袋里面想象,买票这个动作可以看成是一个虚函数,然后新建了普通人买票、学生买票和军人买票,而且还继承了这个虚函数,重构的虚函数里面重新根据不同类的人实现了新的方法,这样在买票的时候根据不同类人创建的对象,然后调用同样的方法,最后输出的票价不一样,这就是多态。不同对象调用同一个方法实现不同的效果,就叫做多态。
父类例子,头文件bird.h
//bird.h
#pragma once
class bird {
public:
//virtual必须添加,否则多肽无法实现,调用的都是父类的方法
virtual void fly();
};
bird.cpp实现
//bird.cpp
#include "bird.h"
#include <iostream>
using namespace std;
void bird::fly(){
cout << "鸟起飞" << endl;
}
新建另外一个新类
头文件bigbird.h
//bigbird.h
#pragma once
#include "bird.h"
class bigbird : public bird {
public:
//virtual必须添加,否则多肽无法实现,调用的都是父类的方法
virtual void fly();
};
bigbird.cpp实现
//bigbird.cpp
#include "bigbird.h"
#include <iostream>
using namespace std;
void bigbird::fly(){
cout << "一只大鸟起飞" << endl;
}
然后我们新建一个主函数main.cpp来调用这两个类,实现多态功能,代码如下:
//main.cpp
#include<stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
//多态(程序的扩展性)
//动态多态:程序运行过程中,觉得哪一个函数被调用(重写)
//静态多态:重载
#include "bird.h"
#include "bigbird.h"
//业务函数
void test(bird &p) {
p.fly();
}
int main(void) {
bird p1;
test(p1);
bigbird p2;
test(p2);
return 0;
}
然后执行代码,执行过程如下所示:
首先执行命令#g++ main.cpp bird.cpp bigbird.cpp -o main
生成可执行文件main,然后#./main执行文件,打印如下信息
至此就实现了多态的功能,即是两个不同的对象p1和p2,调用同样的方法fly(),实现了不同的功能,分别打印了不同的信息,就是实现了不同的功能。以上算是最最简单的多态了。
备注:
1、上面的例子中其实是父类和其中一个子类实现了多态,我们如果又另外新建一个smallbird类,然后bigbird和smallbird这两个子类创建对象,也可以实现多态,这里我图方便就只建了一个子类。在上面的例子中,父类bird里面的函数必须是虚函数才可以实现多态,否则在bigbird里面的重构函数不会起作用,最后调用的都是bird类里面的方法,即是最后打印的都是“鸟起飞”,不会打印“一只大鸟起飞”。
2、纯虚函数
含有纯虚函数的类又叫抽象类,只要含有纯纯虚函数,不管还有没有其他函数,都叫抽象类。表现就是在原来纯虚函数的地方赋值为0,如下所示
//bird.h
#pragma once
class bird {
public:
//virtual必须添加,否则多肽无法实现,调用的都是父类的方法
virtual void fly()=0;
};
纯虚函数在父类中不需要实现,实现都在子类中去重构实现,纯虚函数必须在子类重定义才能被调用,因为在父类中其只有申明没有定义;如果不是纯虚函数,在子类中不需要实现,可以正常调用,只是调用的是父类里面的方法,在子类实现,调用就是调用子类里重构的方法。
如果将在bird.h里面新增一个纯虚函数virtual void run()=0;,那么bird类就是属于抽象类了,抽象类是不允许创建对象的,就是抽象main.cpp里面的bird p1;这个是不允许的,会报错,这点切记切记,否则编译马上就会报错