初识:继承特性
继承的基础语法
cpp
class A{
public:
int a;
};
class B:public A
{
public:
int b;
};
B类通过继承A类后,内部会继承一个int变量 a:从下图我们可以看到,B类型的对象mb在通过点运算符访问成员时,自动提示有a成员变量,而且看提示(A::a)我们知道还是A类中的成员变量a,通过继承的手段,让子类也能拥有该成员变量。一般我们将A类称为基类,也叫做父类;B类称为派生类,也叫做子类。
继承的优劣
继承的好处
1.提高代码的可复用性:减少重复代码,避免代码冗余。
2.提高代码的可维护性:如果父类中的代码需要修改,不需要额外修改子类代码
3.为多态的实现奠定基础:通过继承可以实现不同子类对象对同一信号返回不同响应的功能
继承的弊端
1.破坏了子类的独立性:通过继承,子类与父类之间产生了紧密的耦合关系,当父类发生改变时,需要考虑子类功能是否受影响。
2.增加了程序的复杂性:如果程序中继承关系复杂的话,会削弱程序的可拓展性和可维护性
继承方式
C++中class的默认继承方式是private私有继承
下面给出父类代码,该模块后续子类都继承该父类
cpp
class father{
private:
int f1;
protected:
int f2;
public:
int f3;
};
公共继承
继承时使用pubic关键字,使继承方式变为公共继承。在此继承方式下,子类可以访问父类中所有的公共成员。
cpp
class son1:public father{
/*
//隐藏代码
private:
int f1;
protected:
int f2;
public:
int f3;
*/
public:
int s1;
};
保护继承
继承时使用protected关键字,使继承方式变为保护继承。在此继承方式下,子类可以访问父类中的protected权限下的成员以及public权限下的成员,并将public权限缩小为protected权限
cpp
class son2:protected father{
/*
//隐藏代码
private:
int f1;
protected:
int f2;
int f3;
*/
public:
int s2;
};
私有继承
继承时使用private关键字,使继承方式变为私有继承。在此继承方式下,父类中的所有成员都将变更权限为private继承到子类中。此时子类无法访问父类任何成员。
cpp
class son3:private father{
/*
//隐藏代码
private:
int f1;
private:
int f2;
private:
int f3;
*/
public:
int s3;
};
总结:
1.变更权限是指继承过程的权限变更,父类本身成员的权限不变
2.继承只会缩小权限,不会增加权限
复习:
成员权限:
private:私有的,只能在该类内访问
protected:受保护的,该类及子类可访问
public:公共的,该类及子类可以访问,同时定义的对象也可以访问该权限下成员
继承中的对象模型:
继承后,私有成员只是隐藏了,一样会被继承到子类中。
通过sizeof(son)我们也可以得知类的大小为16个字节,是父类的三个int整型变量加上子类的int变量s。一共4*4=16个字节。所以size=16。
构造与析构的顺序
子类继承父类后,子类创建对象时,也会调用父类的构造函数,那么现在的问题就是,二者的顺序是怎么样的呢。
让我们实验一下就可以了。
结果显而易见,先调用了父类的构造函数,再调用子类的构造函数。先析构子类,再析构父类。这个过程其实就类似于一个入栈与出栈的过程。构造顺序非常容易理解:没有父亲哪来的儿子,再记住析构顺序与构造时相反即可,你也不用纠结为啥不是先创建先死亡。事实上,这种现象叫做栈解旋 。
总结:构造时,先父后子;析构时,先子后父。
同名成员问题
在继承时,难免会存在成员名一样的问题。例如父类中有一个成员变量name,子类也有一个成员变量name,那么遇到成员同名的问题,我们该怎么办呢?不要慌,我们有规定。
访问子类成员:直接访问
访问父类成员:指明作用域
例如:
cpp
class father{
public:
string name;
};
class son:public father{
public:
string name;
};
int main(){
son s;
s.name;//访问子类name
s.father::name;//明显访问的是父类name
return 0;
}
尝试运行,通过。明显没有任何错误。
另外,我们说的不单是成员变量,包括成员函数,只要是成员访问方法都是一致的。
初始化参数列表的拓展使用
cpp
class A{
public:
A(int num){
cout<<"int构造"<<endl;
}
};
class B:public A{
public:
B(int num):A(num){
//如果父类没有无参构造
//可以在子类的构造函数中
//利用初始化列表调用父类的构造函数
//可以完成对子类隐藏的父类成员变量的初始化
}
};
多继承语法
C++允许一个类继承多个类
语法:class 子类 : 继承权限修饰符 父类1 , 继承权限修饰符 父类2 ......
多继承可能会引发父类中有同名成员的出现,需要加以作用域区分
C++实际开发中不建议使用多继承
特殊的菱形继承我们需要了解一下。不过我们会放在多态学习时讲解。实际的开发中,能遇到的像输入输出流的类的继承关系中就有菱形继承。这时候我们先简单的知道一下就可以了
谢谢大家!!