C++学习 之 继承(笔记)
1.继承基础:
继承就像是生物里的遗传与变异,即派生类(子代)从基类(父代)那里继承基类的某些特性(遗传),并在此基础上拥有自己的特性(变异)。
C++派生语法:
class Base//定义一个基类
{
//...基类成员
};
class Derived:access-specifier Base//定义一个派生类
{
//...派生类成员
}
其中access-specifier可以是public、private、protected(表示派生类有一个基类)。
以下程序清单从Fish类派生出了Carp和Tuna类的一种简单的继承层次结构:
#include<iostream>
using namespace std;
class Fish //定义Fish类
{
public:
bool FreshWaterFish; void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
}
}; class Tuna :public Fish//定义Tuna类,将继承的Fish类的成员或方法作为自己的public成员或方法
{
public:
Tuna()
{
FreshWaterFish = false;
}
}; class Carp :public Fish
{
public:
Carp()
{
FreshWaterFish = true;
}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}
2.向基类传递参数:
向基类传递参数在初始化派生类对象时有的时候显得很有用。比如上面的Fish类派生出Carp类和Tuna类,可以修改成如下代码:
#include<iostream>
using namespace std;
class Fish
{
protected:
bool FreshWaterFish;
Fish(bool IsFreshWater)
{
FreshWaterFish = IsFreshWater;
}
public:
void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
Tuna():Fish(false) {}//派生类每次定义对象都指出是淡水鱼还是咸水鱼,采用参数列表将bool值传递给基类的构造函数
}; class Carp :public Fish
{
public:
Carp():Fish(true) {}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}
3.在派生类中覆盖基类的方法:
如果派生类中有和基类中的函数名相同,返回值和特征标也相同时,就相当于派生类的方法覆盖了基类的方法。我们还拿Fish类,Tuna类和Carp类来举例子。
用Tuna和Carp类的Swim()覆盖Fish类的Swim():
#include<iostream>
using namespace std;
class Fish
{
protected:
bool FreshWaterFish;
Fish(bool IsFreshWater)
{
FreshWaterFish = IsFreshWater;
}
public:
void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
Tuna():Fish(false) {}
void Swim()//此函数与基类函数在调用上效果相同,基类函数被覆盖
{
cout << "Tuna swim fast" << endl;
}
}; class Carp :public Fish
{
public:
Carp():Fish(true) {}
void Swim()
{
cout << "Carp swim low" << endl;
}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}
上面的程序的结果显示了,在主函数中对象调用方法Swim()时调用的并不是Fish类里的方法了,而是Tuna和Carp自己的方法,这样基类的方法就相当于是被覆盖了。覆盖是的派生类的方法可以自定 义,但如果我们还想使用基类的方法,就必须想办法使得机器可以知道我们调用的Swim()的作用域在哪个范围。
4. 调用基类中被覆盖的方法:
上面说到了我们只需要让机器知道我们调用的Swim()的作用域,就可以使得被覆盖的基类方法重新被调用。我们可以在调用基类方法时使用"::"作用域解析运算符。
以上面的调用Swim()的代码为例:
myLunch.Swim();//调用派生类Carp中的Swim()
my.Lunch.Fish::Swim();//调用基类Fish中的Swim()
如果基类的方法没有被覆盖,则可以在派生类中和调用函数一样来调用基类的方法。如果被覆盖的话就要使用"::"作用域解析运算符。在主函数里调用就是类似语句:"my.Lunch.Fish::Swim();"在派 生类调用基类被覆盖方法时类似于语句:"Fish::Swim"。
5. 在派生类中隐藏基类的方法:
覆盖的一种极端情形就是,Tuna::Swim()可能隐藏Fish::Swim()的所有重载版本,使得使用这些重载版本会导致编译错误。
以下面代码为例:
#include<iostream>
using namespace std;
class Fish
{
public:
void Swim()
{
cout << "Fish swims...!" << endl;
}
void Swim(bool FreshWaterFish)
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
void Swim()
{
cout << "Tuna swim fast" << endl;
}
};
int main()
{
Tuna myDinner; cout << "Getting my food to swim" << endl;
cout << "Dinner:";
myDinner.Swim();
//myDinner.Swim(false); return ;
}
代码在6-17行实现了基类方法Swim的重载,在23-26行实现了派生类方法Swim对基类方法Swim的覆盖。观察发现派生类里只有一个版本的Swim方法,Fish中的Swim的重载版本Swim(bool)版本好像是没 有被覆盖,但其实Swim(bool)也类似被覆盖的情况是没法在派生类或主函数中像调用其他函数那样被调用的。如果我们去掉35行的注释符号,代码就会有编译错误,这也说明了问题。以上说明了在派生类 中覆盖基类的方法时是与函数的参数无关的,只要函数名称,返回值,特征值相同就会被覆盖。
调用基类中被隐藏的方法:
解决方案1:在main函数中使用作用域解析运算符"::"。
myDinner.Fish::Swim();
解决方案2:在派生类中使用关键字using解除对基类方法的隐藏。
class Tuna:public Fish
{
public:
using Fish Swim;//解除对Fish::Swim()重载版本的隐藏,其中不包括与派生类参数也相同的方法。
void Swim(){}
}
解决方案3:在Tuna类中重新定义所有Fish类的被覆盖的方法的重载版本。
C++学习 之 继承(笔记)的更多相关文章
- Python学习的个人笔记(基础语法)
Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...
- hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览
对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看star ...
- hadoop2.5.2学习及实践笔记(二)—— 编译源代码及导入源码至eclipse
生产环境中hadoop一般会选择64位版本,官方下载的hadoop安装包中的native库是32位的,因此运行64位版本时,需要自己编译64位的native库,并替换掉自带native库. 源码包下的 ...
- 开始记录学习java的笔记
今天开始记录学习java的笔记,加油
- 菜鸟教程之学习Shell script笔记(上)
菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...
- Exception类的学习与继承总结
日期:2018.11.11 星期日 博客期:023 Exception类的学习与继承总结 说起来我们上课还是说过的!老师提到了报错问题出现主要分Exception和Error两类!第一次遇见这个问题是 ...
- 深度学习Keras框架笔记之AutoEncoder类
深度学习Keras框架笔记之AutoEncoder类使用笔记 keras.layers.core.AutoEncoder(encoder, decoder,output_reconstruction= ...
- 深度学习Keras框架笔记之TimeDistributedDense类
深度学习Keras框架笔记之TimeDistributedDense类使用方法笔记 例: keras.layers.core.TimeDistributedDense(output_dim,init= ...
- 深度学习Keras框架笔记之Dense类(标准的一维全连接层)
深度学习Keras框架笔记之Dense类(标准的一维全连接层) 例: keras.layers.core.Dense(output_dim,init='glorot_uniform', activat ...
- Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation
原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
随机推荐
- rabbitmq 的安装配置使用
前言: 对于消息队列中间件: #redis: 功能比较全,但是如果突然停止运行或断电会造成数据丢失 #RabbitMQ:功能比较齐全.稳定.便于安装,在生产环境来说是首选的 1.下载软件[下载较慢,请 ...
- Java中indexOf的用法
indexOf有四种用法: 1.indexOf(int ch) 在给定字符串中查找字符(ASCII),找到返回字符数组所对应的下标找不到返回-1 2.indexOf(String str)在给定符串中 ...
- 使用matplotlib绘制常用图表(3)-其他图表绘制
一.绘制三点图 """ 三月份最高气温 a = [12,15,18,6,7,5,6,8,9,10,15,10,4,5,11,10,5,6,12,15,10,5,14,10 ...
- Python3学习笔记(十八):文件上传和下载
文件上传 以人人网上传头像为例,用Fiddler抓取的上传头像接口报文如下 上传头像图片代码: import requests upload_url = 'http://upload.renren.c ...
- vue + ts Vuex篇
Vuex对Typescript的支持,仍十分薄弱,官方库只是添加了一些.d.ts声明文件,并没有像vue 2.5这样内置支持. 第三方衍生库 vuex-typescript, vuex-ts-deco ...
- (七)C语言之顺序结构
- VirtualBox——在Win7的HOST上安装配置虚拟机CentOS7
在Win7为HOST的环境下,安装VirtualBox,在其中安装CentOS7,以Bridge的方式搭建网络环境. 主要配置包括VirtualBox中的网络设置,以及CentOS中的网络配置.另外还 ...
- isEmpty和isBlank区别
isEmpty 判断某字符串是否为空,为空的标准是 str==null或 str.length()==0 StringUtils.isEmpty(null) = true StringUtils.is ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...
- Python 正则表达式【二】
关于前向,后向,匹配,非匹配 Matches if ... matches next, but doesn’t consume any of the string. This is called a ...