多态性、虚函数、纯虚函数和抽象类知识网络构造
请针对多态性、虚函数、纯虚函数和抽象类几个重要知识点,给出你的理解和分析,尽可能条理清晰、全面,分层次、逐条列出。
友情提醒:不要摘抄或者抄袭,用自己的语言组织,构建自己的逻辑体系。
**理解思路:
**多态性其实也就是作用域不同的重载,他们之间的作用范围不一样,那什么又是作于范围不一样?在这里就引出了子类,
父类这样的概念,然而对于同名的函数,我们又要怎么定义?这就又引出来虚函数,虚函数的话就是会形成虚函数表,当
子类出现下一个相同的函数名时就会把相应的虚函数给覆盖掉,所以我们来想,什么函数没有虚函数,答案就是构造函数
,当你的子类创造时他会直接直接调用,这不虚函数就没有意义了,但是析构函数确可以写做虚函数但一般是当他是基类
的时候,才把构造写成虚函数。同样的还有内联函数(静态的嘛),和静态函数(同享共享)。那我们又有问题啦,如果
两个类是平行的关系怎么办?这是又引出了纯虚函数,他的话就是在父类那里加个=0;就好啦。这样我们就可以用两个平
行子类来实现同名的虚函数。但是我们在这里的时候要注意,我们不可以去给纯虚构函数加对象,也就有了这一个特殊的
类,抽象类。拥有纯虚构函数的类都是抽象类。**
注意事项:
多态性:
(1)其实就是同名函数的作用范围和指向
他的话其实在我看和重载没有什么区别,唯一的不同可能就是他们的作用域不同,我们回忆一下,重载之后是不是所有情况下都可以用,这个所有情况就是他的作用域。多态是什么?是父类一层一层继承下来的,比如说
#include <iostream> using namespace std; class 爷爷//定义形状类 { public: virtual void name(){ cout << "我是爷爷"; }; }; class 爸爸 :public 爷爷 { void name(){ cout << "我是爸爸"; }; }; class 崽崽 :public 爸爸 { void name(){ cout << "我是崽崽"; }; };
虚函数:(具体看上面的代码)
(1)注意虚函数的覆盖性
(2)构造函数和友元不可以声明为虚函数
纯虚函数:
(1)注意是“有”纯虚函数的类是抽象类,不可以生成对象,只可以派生,由他派生的类的纯虚函数没有重写的话派生类还是一个抽象类
看完上面的理解思路,你就会知道,崽崽1,和崽崽2两个就是所谓的平行关系
#include <iostream> using namespace std; class 爸爸//纯虚函数 { public: virtual void name()= 0; }; class 崽崽1 :public 爸爸//和崽崽2是平行关系 { void name(){ cout << "我是崽崽1号"<<endl; }; }; class 崽崽2 :public 爸爸//和崽崽1是平行关系 { void name(){ cout << "我是崽崽2号"<<endl; }; }; void display(爸爸 &a)//用于输出 { a.name(); }
抽象类:
(1)抽象类不能被实例化,实例化由它的子类来完成,用的话也一般是引用
(2)抽象方法必须由子类来进行重写
案例
1)声明一个Shape抽象类,在此基础上派生出Rectangle(矩形)和Circle(圆)类;
2)二者都有GetArea( )函数计算对象的面积,GetPerim( )函数计算对象的周长。
#include <iostream> using namespace std; #define PI 3.14 class Shape//定义形状类 { public: virtual void GetArea() = 0;//纯虚函数 virtual void GetPerim() = 0;//纯虚函数 }; class Rectangle :public Shape//矩形类 { public: Rectangle(float a, float b){ c = a; k = b; };//矩形的析构函数 void GetArea(){mj = c*k; cout << "长:"<<c<<endl<<"宽:"<<k<<endl<<"面积是:" << mj << endl;}//定义矩形面积 void GetPerim(){ zc = 2 * c + 2 * k; cout << "周长是:" << zc<< endl; };//定义矩形周长 private://数据 float c; float k; float mj; float zc; }; class Circle :public Shape// { public: Circle(float a) :r(a){};//圆的析构函数 void GetArea(){ mj = PI*r*r; cout << "半径:" << r << endl << "面积是:" << mj << endl; };//定义圆面积 void GetPerim(){ zc = 2 * PI*r; cout << "周长是:" << zc << endl; };//定义圆周长 private://数据 float r; float mj; float zc; }; void display(Shape &a) { a.GetArea(); a.GetPerim(); } int main() { Rectangle m(2,4); cout << "矩形类:" << endl ; display(m); cout << endl << endl; Circle n(4); cout << "圆类:" << endl; display(n); cout << endl << endl; }
**