大家好
欢迎回来继续学习
C++语言程序设计
这一节呢
我们来学习继承方式
我相信大家已经急不可耐了
在前面的
类的继承的语法中呢
大家看到
继承每个基类都有个继承方式
那继承方式到底是什么呢
接下来我们就来看
继承方式的问题
为什么要区分不同的继承方式呢
不同的继承方式
它的差别在什么地方呢
主要是两个方面
一个是
在派生类的内部
派生类的成员
它怎么去访问基类
继承过来的成员
能访问哪些
不能访问哪些
另一个方面就是说
在派生类和基类之外
这个类的派生家族
之外的某个地方
构造一个派生类的对象
然后通过派生类的对象
去调用从基类
继承过来的成员函数
去访问
从基类继承过来的数据成员
那这个时候
它能访问吗
不同的继承方式
在这两个方面
就反映出它的不同了
那么到底有哪些
不同的继承方式呢
在C++中
继承方式一共有三种
一个是公有继承
一个是私有继承
还有一个
介于它们两个中间
叫做保护继承
公有继承呢
实际上是最宽泛的一种继承
也是我们写程序中
最常用的一种继承
尤其是初学的同学们
你就尽量用公有继承就行了
为什么呢
一会你就看到了
公有继承
它是基类里面的public
和protected成员
它继承过来以后
在派生类中
它的访问控制属性
都保持不变
所以原来public还是public
原来的protected还是protected
但是
注意啊
这个private成员
它就不能直接访问了
这个大家可以理解吗
私有的嘛
我们人有时候继承遗产的时候
某个遗产还附加一个条件的
不是说这个遗产给你
你就直接可以用了
我附加什么条件才能给你
对吧
我们人类社会有这样的情况
那程序中呢
也给你留了这样一种途径
那么私有成员呢
到了派生类中
派生类的成员函数
就不能直接访问
从基类继承过来的私有成员
那你说这私有成员
有什么用啊
继承过来光占地还不能用
不是
你要用也可以
一般来说
我们的类为私有成员
都提供了公有的访问接口
所以只要基类
提供了公有访问接口
那派生类的成员
可以通过公有访问接口
也就是有条件地去使用
基类继承过来的私有成员
那么这项规定有什么用呢
其实是非常有用的
我们知道基类
可能是另外一个团队开发的
可能是随着软件包
带来的这种类库
那么我们派生类的编写者是谁呢
是我们现在
比如说
我们这个应用程序的开发者
我拿那个类库来以后
有一些类可以用
我把它继承过来
那里面的私有成员
当然应该不可直接访问
为什么呢
因为我都不知道它是什么
不让我直接访问它最好
对吧
那么派生类中的成员函数
可以访问基类的公有和保护成员
但是不能访问私有成员
这就是一个规则
那么通过派生类的对象呢
从类外只能访问公有成员
这个跟原来学过的规则是一样的
下面呢
我就来给大家演示一个
公有继承的例子
在这个例题中呢
我们看定义了一个点类
point类
定义了一个矩形类
用公有方式继承了点类
然后在主函数中
我们要定义一个矩形类的对象
观察一下
通过这个对象
去调用的这些成员函数
都是哪个类定义的函数
好 现在我们通过单步执行
跟踪进去
进到这个主函数里面
构造了一个矩形对象
所以这个时候呢
我们看到对象里面
构造完了以后
没有含有有意义的数据
是垃圾数据
因为在有继承的情况下呢
写构造函数
要关注的因素比较多
所以在这个例题中
不管是点类
还是矩形类中
我们都没有显示的定义构造函数
那就由编译器在需要的时候
为我们隐含生成默认的构造函数
那这个隐含生成的默认构造函数
因为它是不进行
任何实质性的初始化工作的
所以构造完以后
这个矩形的对象呢
它没有一个确定的初始值
因此呢
我们还是需要对这个对象
进行一下初始化
这个初始化呢
我们就写了一个
普通的成员函数initRectangle
来进行这个初始化
当然这个函数
它是不会被自动调用的
所以大家看到
在程序中呢
我们要主动的显示着
去调用这个函数
把初始参数列进来
列到参数表里面
这个初始参数呢
前两个我们希望用来
作为点的坐标
后两个呢作为宽和高
也就是说
前两个是表示矩形的位置
后两个表示矩形的宽和高
那我们来看这个
进到这个rectangle
它的initRectangle函数以后
会怎么样执行
好 那么我们再按f11
追踪到这个函数里面
现在进来了
这个函数是要初始化这个矩形
但是呢
只有宽和高
是矩形类自己新增定义的
另外
这个矩形的位置
是继承了这个点类
也就是说
这个矩形的位置x y坐标
是它基类的私有成员
所以在这个rectangle类的函数中
是不直接访问的
怎么办呢
基类中定义有
这种公有接口函数
initPoint
我们可以调用这个函数
来对x y进行初始化
所以这里呢
我们调用initPoint
我们看到进到initPoint里面来
执行完了以后
然后再对本类的宽和高赋值
这样就完成了点的初始化
回到主函数中
我们看到点现在有值了
大家看
它里面内嵌了一个point对象
坐标是我们给它的2和3
然后宽和高是20和10
接下来再移动矩形的位置
通过rect这个对象
去调用move函数
但是我们看rectangle这个类里面
并没有写move函数
但是呢
point类里有个move函数
这个move就被继承到
rectangle里面了
并且它原来是公有的
rectangle用公用方式继承point
所以继承过来
它依然是公有的
现在我们可以在主函数中
去直接调用它
看看进到哪个函数里面了
进到point类的move函数里面了
执行完了以后
回到主函数
接下来呢
我们来调用
这些get函数
首先
我们来看
进到了getH里面
把H值取回来
再往下走呢
我们进到getW里面
把W值取回来
再往下走
我们看进到了getY里面
这是基类point类定义的
公有函数成员
说明它确实被继承到了
tangle里面
而且依然是公有的
所以我们才可以在类外
通过对象调用它
再次追踪
进到了getX函数里面
好
这些get函数都执行完了以后
就接下来会继续完成
我们要执行的这个输出
执行完了输出以后
我们来看这个输出结果在这儿
执行完了输出以后
那么程序到return这儿结束
所以通过这个例子
我们可以看到
基类的公有成员继承过来
用公有方式继承过来
都是公有的
基类的私有成员
用公有方式继承过来
在派生类的成员函数中
是不能直接访问的
要调用它的公有接口访问
然后在类外定义
派生类的对象的时候
可以通过派生类的对象
去访问
派生类自己定义的公有函数
也可以访问
从公有基类继承过来的
原有的公有成员函数
继承过来
仍然是公有 仍然是public