目录
1.继承的含义
2.继承的定义:
3.继承方式
例子1:基类的访问限定符为public,两个派生类的继承方式分别为public、protected时:
例子2: 基类的访问限定符为protected,两个派生类的继承方式分别为public、protected时:
继承方式解析:
总结:
面向对象的三大特性为:封装、继承、多态。今天我们来学习第二大特性:继承!
例:
当我们在做一个学校教务管理系统时,会有老师、学生、教务人员(非老师)三种对象,管理系统的任务需求主要是对这三类对象进行信息的填写,资料和完善。在代码方面,这三类对象因为所处的身份不同,各自的属性也就大不一样,但是也有一些相同的地方,例如:名字、性别、年龄、家庭住址、电话号等等。这三类对象都有这些相同的属性,意味着代码上会有冗余,降低了代码的可读性。之还只是一个小小的管理系统,若是在公司做那种大项目,需要成白上千个类,若是这些类都像上面这个管理系统一样,都有重复的代码。那么冗余的代码就不止几十行了。
于是设计C++的大佬们为了解决这种问题,创造出了面向对象的新特性:继承。
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
上图中下方创建出的这三个类通过特定的方式继承上面的Person类,这样一来,下面的这三个类就可以随意使用Person类中的成员属性,根本不需要再自己写这三个类都有的属性,这就好比父亲辛辛苦苦打下来的基业,他的儿子们可以轻松的获取到。
#include
using namespace std;
//父类
class Person {
public:
void Print() {
cout << " name: " <<_name<< endl;
cout << " address: " <<_address<< endl;
cout << endl;
}
public:
int _id;
string _name="LiMing";
int _age;
string _address="TaiYuan";
};
//子类1
class Student :public Person {
public:
void crint() {
_name = "YuQing";
cout << " name: " << _name << endl;
cout << " address: " << _address << endl;
cout <<"班级名称:" << _className << endl;
cout << "所在年级:" << _grade << endl;
cout << "年龄:" << _age << endl;
cout << endl;
}
private:
string _className="2001班";
int _grade=3;
};
//子类2:
class Teacher :protected Person {
public:
void Print() {
cout << " name: " << _name << endl;
cout << " address: " << _address << endl;
cout << "所教科目:" << _post << endl;
cout << endl;
}
public:
string _post="语文";//职务
};
person类是父类,也可以称作是基类。Student是子类,也可以称作是派生类。一般的叫法是父类子类为组合,或者基类派生类为组合。
继承的方式有三种:public(公有继承)、protected(保护继承)、private(私有继承)
这三个单词也作用于类的访问限定符,设置为public的成员,类内类外都可以进行访问;设置为protected、private形式的成员,只有类内可以访问,类外不允许访问,也就是说在学到继承的特性之前,protected和private的作用是一样的,没有区别。
但是学习了继承之后,protected和private的区别就展现出来了。如下:
如上图,表示的是父类的成员访问限定符是public、protected、private时,子类采用public、protected、private继承方式继承时,能否访问到的情况:
举两个例子:
在该例中,由于基类的成员都是公有的,派生类中可以随意地对继承过来的成员进行读写。而由于两个派生类的继承方式不同,类外在创建派生类的对象时,能够使用的成员权限却是不一样的!!!
类外创建了两个类的对象:
派生类1(公有继承的):
派生类Student中并没有设置_age,_name等成员变量,但是在类外能够设置成员变量值,就是因为Student派生类公有继承了基类Person类的所有公共成员(包括函数和成员变量),基于此,Student类对象便可以随意访问Person类的公共成员,并为其设置值,增强了代码的复用性。
类外通过公有继承的派生类对象访问任何基类成员都是成功的
派生类2(保护继承的):
因为Teacher子类是保护继承了父类Person类,在Teacher类中可以访问Person类的公有保护成员,但在类外却不能被访问,所以上面的前两行代码报错了。
类外通过保护继承的派生类对象访问任何基类成员都是失败的
注:当派生类是私有继承基类时,派生类内仍然可以随意读写从基类继承过来的成员,但是类外就不能使用派生类的任何成员。
当基类的访问限定符是protected时,两个派生类分别公有继承和保护继承基类,这两个派生类仍然可以随意读写访问基类成员。
在类外:
类外通过公有继承的派生类对象访问任何基类成员都是报错的。
类外通过保护继承的派生类对象访问任何基类成员都是报错的。
1.基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
2. 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。这就是protected和private两个关键字的最大区别!
3. 实际上面的表格我们进行一下总结会发现,基类的私有成员在派生类中都是不可见。基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),所以权限上:public > protected> private。4. 使用关键字class创建出的类,如果不写继承方式时,默认的继承方式是private,使用struct关键字创建出的类,如果不写继承方式时,默认的继承方式是public,不过最好显示的写出继承方式,可以增强代码可读性。
5. 在实际运用中派生类一般都是使用public继承方式,几乎很少使用protetced / private继承,并且我们也不提倡使用protetced / private继承,因为protetced / private继承下来的成员都只能在派生类的类里面使用,类外(主函数执行流中)是没有办法使用子类的成员的,实际中扩展维护性不强。
1.基类的访问限定符限制了派生类能否访问读写基类的成员;
2.而派生类的继承方式限制了类外能否访问读写派生类的成员!