面向对象的三大基本特征:封装,继承,多态。
继承是模拟现实世界和代码复用的重要手段。一个类可以派生出另一个类,从而实现代码复用。举个例子,人拥有身份证号的属性,学生则拥有普通人没有的学号,那么在定义学生时还需要加一个变量来表示身份证号吗?确实没必要,可以直接让学生继承人的类,就可以实现代码的复用。
C++ 通过类派生( cass derivation) 的机制来支持继承。被继承的类称为基类 (base class) 或超类 (superclass),新产生的类为派生类 (derived class) 或子类 (subclass) 。基类和派生类的集合称作类继承层次结构 (hierarchy) 。
由基类派生出,派生类的设计形式为:
class 派生类名 : 访问限定符 基类类名 {
};
例如:
class Person
{
private:
int id_num;
public:
Person(int id=0) :id_num(id)
{
}
~Person(){}
void fun_p()
{
cout << "work" << endl;
}
};
class Student : public Person
{
private:
int s_num;
public:
Student(int id=0, int num=0) :Person(id), s_num(num)
{
}
~Student(){}
void fun_s()
{
cout << "study" << endl;
}
};
学生继承了人,人有一个方法为工作,学生有一个方法为学习。
接下来看一下学生都有那些属性构成:
当我们定义学生类型的变量st时,可以看到:学生类型中有俩个部分组成,一个是基类的成员,一个则是自己的。基类成员中又有身份证这个属性。继承结构就基本是这样。
构造函数和析构函数不能被继承。 我们知道构造函数和析构函数是跟对象的创建与消亡的善后工作相关。我们所创建派生类的对象,虽然和基类的对象有相同之处,但是仍然是不同的对象。所以,适用于基类的构造函数和析构函数不可能完全满足派生类对象的创建和消亡的善后工作。因此,构造函数
和析构函数不被继承。第二: 其他函数都可以通过类对象来调用,创建对象时由系统调用该对象所属类的构造函数,在该对象生存期中也只调用这一次。由继承而来的派生类对象,是能够调用父类的函数,但不能调用构造函数也不能调用析构函数
继承方式,亦称为访问控制,是对基类成员进一步的限制。继承方式也是三种
公有 (public) 方式,亦称公有继承
保护 (protected) 方式,亦称保护继承
私有 (private) 方式,亦称私有继承
不同继承方式的区别:
采取公有继承,私有继承或者保护继承都可以。无论采取何种继承方式,都会把基类中的所有东西(除了构造函数,拷贝构造,赋值运算符重载以及析构函数以外的所有东西)继承下来,相当于拷贝了一份在派生类中。但是,这三种继承是有区别的:
从语法结构上来说:无论采取何种继承方式,在派生类中的成员方法都可以直接访问基类中的保护和公有成员,但是访问不了私有成员。但是采取公有继承的时候,外部函数可以直接访问基类的公有成员,不能访问基类中的私有和保护成员。但是当采取私有继承或者保护继承的时候,外部函数不能访问基类中的所有成员。
既然构造函数和析构函数不能被继承,那么就需要重写派生类的构造函数。当程序进入到派生类的构造函数时,先去遍历初始化列表,然后即使程序设计者没有明确给出要调用基类的构造函数,编译器仍然会先调用基类的构造函数,然后再来初始化派生来的成员,来构建派生类中的对象。当然,当对象结束的时候,系统会先调用派生类的析构函数,然后再来调用基类的构造函数。
总结
1.不论采取何种继承方式,基类中所有数据成员都将继承到派生类2.在类型的继承层次结构中,保护属性当作公有属性来使用。
3.继承性具有传递性。
4.无论采取何种继承方式,派生类对象的成员方法都可以去访问基类对象中的保护和公有属性。