一、什么是继承?
继承通俗的讲就是子承父业。就像古代地主家的儿子就像一个派生类/子类,地主就是基类/父类。地主的儿子会继承他爹的家产。
继承就是在一个类的基础上,由于出现新的功能,而又要保持原来基本的功能,就在此类基础上进行扩展。这样生成的类被称为派生类/子类。原有的来被称为基类/父类。继承是面向对象程序设计的层次结构。从复杂的类慢慢衍生到复杂,继承是类设计层次的复用。
在C++中继承就是在一个类的基础上后面加上继承方式和所继承的类名,继承方式有三种public,protected,private三种,我将一一介绍。
(一)首先看看public继承是如何使用,代码显示:
#include<iostream> using namespace std; class Base { public: void SetInfo(int pri, int pro, int pub) { _pri = pri; _pro = pro; _pub = pub; } void Print() { cout << "_pri = " << _pri << endl; cout << "_pro = " << _pro << endl; cout << "_pub = " << _pub << endl; } private: int _pri; protected: int _pro; public: int _pub; }; class children : public Base { public: void SetChInfo(int chpri, int chpro, int chpub) { _chpri = chpri; _chpro = chpro; _chpub = chpub; } void ChPrint() { cout << "_chpri = " << _chpri << endl; cout << "_chpro = " << _chpro << endl; cout << "_chpub = " << _chpub << endl; } private: int _chpri; protected: int _chpro; public: int _chpub; }; int main() { children C; cout << "sizeof(C) = " << sizeof(C) << endl; C._pub = 5; C.SetInfo(6, 6, 6); C.SetChInfo(7, 8, 9); C.Print(); C.ChPrint(); system("pause"); return 0; }
运行结果:
在公有的继承中,子类将继承父类的所有public和protected修饰的成员,注意protected修饰的成员只能在子类类中访问,不能再类外访问。
(二)protected继承方式来继承父类,在子类的访问父类情况。
#include<iostream> using namespace std; class Base { public: void SetInfo(int pri = 1, int pro = 2, int pub = 3) { _pri = pri; _pro = pro; _pub = pub; } void Print() { cout << "_pri = " << _pri << endl; cout << "_pro = " << _pro << endl; cout << "_pub = " << _pub << endl; } private: int _pri; protected: int _pro; public: int _pub; }; class children : protected Base { public: void SetChInfo(int chpri, int chpro, int chpub) { _chpri = chpri; _chpro = chpro; _chpub = chpub; } //注意protected修饰的父类的所有变量均不能通过子类在类外访问, //但是可以在子类中访问父类的保护变量和公有变量 void SetBaseInfo(int pro, int pub) { _pro = pro; _pub = pub; } void PrintBaseInfo() { cout << "_pro = " << _pro << endl; cout << "_pub = " << _pub << endl; } void ChPrint() { cout << "_chpri = " << _chpri << endl; cout << "_chpro = " << _chpro << endl; cout << "_chpub = " << _chpub << endl; } private: int _chpri; protected: int _chpro; public: int _chpub; }; int main() { children C; //一旦继承的类的权限变为protected,那么子类在访问父类时将至少父类里面的所有成员都是protected,限制越来越高。 //当然比protected高的private仍旧是private cout << "sizeof(C) = " << sizeof(C) << endl; //不能在类外访问,此时已经变为protected修饰的变量_pub //C._pub = 5; //C.SetInfo(6, 6, 6); C.SetChInfo(7, 8, 9); //C.Print(); C.ChPrint(); C.SetBaseInfo(2, 2); C.PrintBaseInfo(); system("pause"); return 0; }
在继承方式为protected时,父类中的public修饰的成员已经不能在子类的类外访问。他已经变为protected了,若要证明变为protected则在子类的基础上再继承子类。然后通过这个来访问第一个类便可以得知。,所以可以在子类中进行访问及操作。而父类中protected和private修饰的成员依旧和以前一样,protected修饰的可以在子类中访问但不能在类外访问。private修饰的成员则不能在类外访问,在子类中也不可以访问。
(三)private继承方式的类
class Base { public: void SetInfo(int pri = 1, int pro = 2, int pub = 3) { _pri = pri; _pro = pro; _pub = pub; } void Print() { cout << "_pri = " << _pri << endl; cout << "_pro = " << _pro << endl; cout << "_pub = " << _pub << endl; } private: int _pri; protected: int _pro; public: int _pub; }; class children : private Base { public: void SetChInfo(int chpri, int chpro, int chpub) { _chpri = chpri; _chpro = chpro; _chpub = chpub; } //注意private修饰的父类的所有变量也均不能通过子类在类外访问, //但是也可以在子类中访问父类的保护变量和公有变量,原有的私有变量不可访问 void SetBaseInfo(int pro, int pub) { _pro = pro; _pub = pub; //_pri } void PrintBaseInfo() { cout << "_pro = " << _pro << endl; cout << "_pub = " << _pub << endl; } void ChPrint() { cout << "_chpri = " << _chpri << endl; cout << "_chpro = " << _chpro << endl; cout << "_chpub = " << _chpub << endl; } private: int _chpri; protected: int _chpro; public: int _chpub; }; //验证private限定的继承类在子类中是什么权限 //变为私有 //说明在private限定的继承类的直接子类中已经再次将父类中的public,protected修饰的变量改为私有, //但直接子类中还可以访问二者,但是在继承的孙子类中就不可在访问这两者变量 //class SZ : public children //{ //public: // void Test() // { // _pub = 6; // _pro = 6; // } //}; int main() { children C; C.SetBaseInfo(6, 6); C.PrintBaseInfo(); //C._pub = 8; //SZ S; //S.Test(); system("pause"); return 0; }
当继承方式是private时,此时在这个子类中已经将父类的所有成员设置为private。在子类中仍旧可以访问父类的public和protected修饰的成员,但是此时父类的所有成员已经变为private修饰。为什么子类中仍可以访问呢?这就好比一个类中自己修饰的private成员变量,在自己类中可以访问一样。
在子类的类外就不能访问父类的任意成员了。如何说明呢?那就再创建一个子类的来继承这个子类。在创建的子类中就可以尝试访问第一个类中的成员。发现不可访问。
(四)赋值兼容规则
子类和父类之间的赋值有以下特点:
前提;继承方式必须是public继承方式
子类对象可以看成是一个父类的对象(在所有用到父类对象的位置都可以使用子类对象代替)
验证:1.从类外对父类对象的使用方式
2.从对象模型的角度(两个图)1.可以将子类对象赋值给基类对象,但是不能用基类对象给子类对象赋值。
2.基类对象的指针(引用)可以指向(引用)子类对象,但反过来就不可以。
3.基类对象指针赋值给子类对象时,可以强转,但是这可能不安全。访问越界。
(五) class 和 struct区别
1.在类上class默认私有限定,而struct默认共有
2.在模板的参数类型可以使用class但不能使用struct
3.当继承权限没有给时,当用class实现类 默认private 而struct --->public
(六)同名隐藏
1.如果子类与父类具有相同名称的成员(可以是成员变量成员函数)
成员变量同名:是否与父类同名成员类型相同无关
成员函数同名:是否与父类同名的成员函数原型一致无关
2.隐藏:
如果使用子类对象访问同名成员,优先访问子类自己成员,父类同名成员不能直接访问(子类同名成员将父类同名成员隐藏)
一定要通过子类对象访问父类同名成员:加父类的作用域(类名)
所以继承中子类和父类最好不要同名。珍&源码