继承和多态 1.0 -- 继承概念(is-a、has-a,赋值兼容规则,隐藏重定义)
普通继承和访问权限
当一个继承没有虚拟继承或者是多重继承时,就是一个简单的继承的时候,这个时候就是一个普通的继承。
普通继承的内存空间是:子类的对象中,包含了父类的成员变量,同时也可以调用父类的成员函数(有些情况不可以,比如访问权限和重定义)
访问权限:比较继承方式和父类的成员修饰符 – 二者取权限低的那个。这里的访问权限,指的是子类在类内部访问父类成员的权限和子类对象在类外访问的权限。
(总结:一般继承时,父类用的是public)
问题:没有合适的构造函数
我们在编程的时候,经常会遇到一种情况就是,没有合适的构造函数,这个时候的可能有以下几种原因:
- 构造函数的参数不匹配,比如我们定义的一个构造函数是没有参数的,然后使用类实例化一个对象的时候,传递了一个参数,这个时候没有合适的构造函数;同样的道理就是,我们定义的构造函数有参数,但是我们使用类实例化一个对象 的时候,却没有传递一个参数,这个时候也是没有合适的构造函数。这里我们引入一个概念,就是default构造函数,这个意思就是,我们在使用类实例化一个对象的时候,可以不用传参数,这种情况可以是,我们定义的构造函数是不带参数的,还有一种情况是,我们的构造函数带参,但是这个参数是一个缺省值。
- 第二种情况就是,我们的子类继承了父类,这个时候,子类在调用构造函数的时候,需要合成一个构造函数,就是先调用父类的构造函数,然后再调用自己的构造函数,把这两个 合成了一个构造函数,这个样子就是可能存在实例化一个对象的时候,给 父类传递的参数 不正确。
#include<iostream>
using namespace std;
class A
{
public:A(int a):_a(a){}
public:int _a;
};class B : public A
{
public:B(int a):_b(0), A(a) //这一步非常重要,必须要显式的构造书一个无名的父类的对象{}
public:int _b;
};int main()
{A a(0);B b(0); //这个0参数实际是父类需要的参数a = b;return 0;}
上面我们应该注意的一个问题就是,我们需要在子类(B)里面显式的构造出一个无名的父类对象
is-a和has-a
public继承时一个接口继承,是is-a原则
一个子类就是一个父类,因为父类的所有内容都可用(is-a)
protected/private继承是实现继承,父类的成员有一部分子类是无法继承的
一个子类中有一个父类,但是部分父类的成员是不可用的(has-a)
总结:这里所说的is-a和has-a仅仅限于继承的方式上面,就是如果是 public继承则是is-a,如果是其他两种继承方式则是has-a。不用考虑父类里面的访问限定符。
关于is-a的设计:我们知道公有继承是is-a的关系,但是我们不能滥用is-a,is-a代表的一种模型是,父类的每个操作,子类都能够执行,但是我们必须注意的一个问题就是,父类的有些操作子类是执行不了了,我们在设计的时候,还需要考虑现实的生活,比如我们设计了父类:鸟。鸟里面有有一个函数是fly,这里有设计了一个子类,企鹅,采用的继承方式是公有继承,但是这里显然 存在了一个问题,就是企鹅是 不会 fly的,所以上面的设计是不合理的。这里我们还应该考虑的一个问题就是,我们应该如何设计呢,两种方式,一种是在鸟类中不设计fly,然后子类继承的时候采用公有继承,可以自己定义一个fly函数,还有一种设计是,我们在鸟类中定义了fly函数,然后子类继承的时候在进行重定义或者是重写,然后企鹅中告诉我们“企鹅不会飞”。比较上面的两种方式我们发现,第一种 方式更合理一些,第二种方式显得更加的冗余了。
再来看一个例子,我们一般的认为是,一个正方形就是一个长方形,但是在设计长方形的时候,我们可以设计一个函数,改变面积,此时函数 的功能是只增大长度而不增加宽度,但是 我们 的正方形继承之后,显然这个增加面积的函数对于正方形这个类是错误的,因为我们的正方形要是定义了函数之后,正方形就不在是正方形了。
综上:我们在使用公有继承的时候,想使用is-a,就要在设计父类的时候,检查父类的所有操作是否完全符合子类的要求。
赋值兼容规则 – 必须是公有继承(is-a)
我们先来看一个图,看看普通的继承内存是如何分配的
所谓赋值兼容规则就是,子类是一个父类,这个时候子类是可以赋值给父类的,这种赋值 包括三种行为,一种是子类的额对象赋值给父类,一种是子类的指针赋值给父类,还有一种是子类的引用赋值给父类
上面的三种行为均发生了切片行为,或者叫做是切割行为。
反过来思考一个问题就是,我们的父类可以赋值给子类吗,原则上是不可以的,比如A是父类,B是子类,下面的方式不可以的
A a;
B b;
b = a; //错误
B& rb = a; //错误
B* pb = &a; //错误
从内存上面我们很好的理解上面的结果,但是如果我们使用了强制类型转换就可以改变其中的一部分,比如下面的行为是正确的
A a;
B b;
B& rb = (B*)a; //错误
B* pb = (B&)&a; //错误
原因很简单,如果是 对象赋值的话,父类的内存空间要比子类小的,无法完成赋值,但是指针和引用不一样,指针和引用的大小是没有变得,指针是四个字节,只是把类型强制 转化一个就可以了,但是有人可能会费解的一个问题就是,为什么引用可以呢,引用不是指针呀,其实解释是这个样子的,引用的底层实现其实也是一个指针。
重定义 – 把父类成员隐藏起来
什么是隐藏
子类和父类有相同名字的成员(成员变量或者是成员函数),这个访问 子类的成员的时候,就会自动的把父类的成员隐藏起来(父类是没有虚函数的)
如何理解和记忆
父类定义了一个函数或者是成员变量,然后在子类中定义了相同的成员函数或者是变量,这个时候就相当于把父类的成员 函数或者是成员变量隐藏起来了。
重定义是方法,隐藏是结果
(同样的道理,我们也可以理解虚函数的重写,重写是方法,覆盖是结果)
相关文章:

c++标准库 及 命名空间std
1、命名空间std C标准中引入命名空间的概念,是为了解决不同模块或者函数库中相同标识符冲突的问题。有了命名空间的概念,标识符就被限制在特定的范围(函数)内,不会引起命名冲突。最典型的例子就是std命名空间,C标准库中所有标识…

aop point 只能获取到map嘛_面试被问了几百遍的 IoC 和 AOP ,还在傻傻搞不清楚?...
这篇文章会从下面从以下几个问题展开对 IoC & AOP 的解释什么是 IoC?IoC 解决了什么问题?IoC 和 DI 的区别?什么是 AOP?AOP 解决了什么问题?AOP 为什么叫做切面编程?首先声明:IoC & AOP…

HTML学习笔记_002_如何学习HTML
.htm 还是 .html 文件后缀? 当您保存 HTML 文件时,既可以使用 .htm 也可以使用 .html 文件后缀。我们在实例中使用 .htm。这只是长久以来形成的习惯而已,因为过去的很多软件只允许三个字母的文件后缀。 不过对于新的软件,使用 .ht…

设计1.0 -- iterator 和const_iterator底层的模拟实现
本文概要: 本文主要是模拟实现STL中迭代器和const迭代器的,主要阐述的一个问题就是,为什么我们在设计迭代器的时候需要使用三个模板参数呢 在设计迭代器的时候,我们有下面的代码 #include<iostream> using namespace std…

关于python缩进的描述中_关于Python程序中与“缩进”有关的说法中,以下选项中正确的是()...
关于Python程序中与“缩进”有关的说法中,以下选项中正确的是()答:缩进在程序中长度统一且强制使用同文学或同音乐主题的民歌,《_______》是其中之一。此曲经民间艺人丁喜才改编后,由上海音乐学院鞠秀芳于50年代在国际上唱红答:五…

使用Newtonsoft.Json
首先是前一段某博友对于循环引用的问题的解决:http://www.cnblogs.com/Gryzor/archive/2013/05/06/3062373.html 其次是时间到底是UTC还是Local的问题:http://www.cnblogs.com/leonwang/archive/2013/05/29/javascript-datetime.html 对于第二条…

回击质疑 HP StoreOnce用高性能说话
四五年以前,记者曾经两次参观过惠普位于英国西南部港口城市布里斯托尔的存储研究中心,那里是惠普数据备份和保护产品的大本营,同时也是惠普磁带产品与HP StoreOnce产品家族的诞生地。就在惠普刚刚发布升级版的HP StoreOnce B6200以及Catalyst…

windows10配置jenkins
1、下载pscp.exe并拷贝到c:\window\system32,此工具用于上传文件至linux服务器 下载地址:https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html 2、下载jenkins.war 下载地下:https://jenkins.io/download/ 3、设置环境变量JENKI…

STL模拟实现1.0 -- list和iterator模拟实现和简单分析
引言 C 标准模本库《STL》中有很多优秀的代码实现,不然怎么能叫做C标准模板库呢,其中一个实现就是有一个容器,叫做list。所谓容器其实就是存储相同类型数据的一个存储集合,list的底层实现其实就是一个链表。 我们的普通数组在使…

hdc mfc 画扇形图_使用echarts绘制条形图和扇形图
使用echarts绘制条形图和扇形图简单举例说明下echarts如何绘制条形图和扇形图代码示例echarts绘制条形图和扇形图var mychart1echarts.init(document.getElementById(chart1),light);// 指定图表的配置项和数据var option {title: {text: ECharts 入门示例},tooltip: {},legen…
Java学习笔记45:Java 线程与主线程之间的变量关系
运行下面的代码: package com.test.www;public class Test {public static int count 0;public static void inc() {//这里延迟1毫秒,使得结果明显try {Thread.sleep(1);} catch (InterruptedException e) {}count;}public static void main(String[] a…

会计的思考(36):会计--企业运营的数码相机
新浪网上看到一张图片,拍的是2009年12月3日的武汉市,整个城市在笼罩在一片污浊空气当中,让人震惊。虽然我在深圳,但也清楚好不到哪去。 震惊之余,感谢新浪,更感谢某位摄影师,让我们了解到生活的…

spring cloud连载第二篇之Spring Cloud Config
Spring Cloud Config Spring Cloud Config为分布式服务提供了服务侧和客户侧的外部配置支持。通过Spring Cloud Config你可以有一个统一的地方来管理所有应用的外部配置。 默认服务端存储实现用的是git,因此,它很容易支持配置环境的标签版本,…

CodeOnly
关于设置[Key]标志 要先添加 程序集的引用 在添加 using System.ComponentModel.DataAnnotations; 命名控件转载于:https://www.cnblogs.com/since87/archive/2013/06/09/3129399.html

继承和多态 2.0 -- 继承的六个默认成员函数
本文重要介绍普通继承中如何写派生类的六个默认成员函数,主要是针对在派生类中,如何调用基类的六个默认成员函数 需要说明的一点就是,如果子类中没有调用父类的函数时,系统会自动生成一个。 构造函数 子类中有父类的成员&#…

js 让鼠标右下角有一排小字_js布局中一排大字下面接着一排小字怎么打出来?...
展开全部可以使用 TypewriterJS 实现效果是这样 ,百度图片少了一部分,可以通过链接32313133353236313431303231363533e78988e69d8331333433626438看效果链接: 网页链接示例在这里: 网页链接文档地址: 网页链接使用步骤引用 TypewriterJShtmlcss.article__title {fon…

Hudson神奇的环境变量
Hudson神奇的环境变量 http://blog.sina.com.cn/s/blog_798f21a00100z6zw.html转载于:https://blog.51cto.com/myloveworld/950156

英语影视台词---四、Sideways
英语影视台词---四、Sideways 一、总结 一句话总结:杯酒人生 Sideways,大致意思是“偏离、倾斜、转向…”。很明显中文译名与英文原名并没有什么关联,《杯酒人生》这个名字,其实也可以译为《并肩前行》,应该是从影片内…

继承和多态 3.0 -- 菱形继承
单继承和多继承 C的继承方式是支持单继承和多继承的,首先看一下代码,分清单继承和多继承 单继承 class A { public:int _a; };class B :public A { public:int _b; };class C : public A { public:int _c; }; 类似于上面的方式就是单继承,或…

C# split 几种使用方法
第一种方法: string s "abcdeabcdeabcde"; string[] sArray s.Split(c); foreach (string i in sArray) Console.WriteLine(i.ToString()); Console.ReadKey();输出下面的结果:abdeabdeabd…

模糊匹配 读音_onenote搜索机制详解②:两种搜索模式,模糊与精确匹配
先从纯文本搜索讲起,这是最基本也是最重要的。从这篇开始,以及接下来连续几篇文章,都会介绍搜索的基础功能。注意,这几篇文章中谈论的都是基本的、正常的搜索功能,暂时不考虑Bug等因素。在很多软件(例如wor…

EXT3与EXT4的主要区别
Linux kernel 自 2.6.28 开始正式支持新的文件系统 Ext4。 Ext4 是 Ext3 的改进版,修改了 Ext3 中部分重要的数据结构,而不仅仅像 Ext3 对 Ext2 那样,只是增加了一个日志功能而已。Ext4 可以提供更佳的性能和可靠性,还有更为丰富的…

Java IO 4 : RandomAccessFile
RandomAccessFile: 认识:java输入/输出流体系中功能最丰富的文件内容访问类 既可以读取文件内容,也可以向文件传输数据,并且支持“随机访问“的方式,程序可以跳转到任意地方来读写数据。 特点:与OutputStream/Writ…

二叉树 1.0 -- 创建二叉树、遍历二叉树、二叉树常见问题求解
树的结构主要是为了查找,这个主要是为了搜索,树的结构关注的不是增删查改 树 广义上面的树的结构我们不知道树的一个节点是有几个子节点的,所以这个时候我们需要定义的一种结构就是,一个节点的孩子是可以动态的增加的࿰…

impala 本年格式化时间_hive,hbase,impala之间的对比
hbase在三者中更注重的是存储,它实现了类似mysql的double write机制,但是它是一种NoSQL的数据库,并且是可以支持列式存储的,算是比较大的一个内存Hash表。hbase也采用了类似mysql中的mvcc的思想通过时间戳来做版本控制。hbase是在…

简单上手的游戏引擎
物理游戏引擎 GameSalad 转载于:https://www.cnblogs.com/sgdkg/archive/2013/06/14/3135882.html

Linux内核中关于定时器Timer的应用
2019独角兽企业重金招聘Python工程师标准>>> 在Touchscreen驱动中 1 声明 Ad7877.c (\linux-2.6.30.4\drivers\input\touchscreen): struct timer_list timer; /* P: lock */ 2 初始化 在函数 static int __devinit ad7877_probe(struct spi_device *spi) 中 执行 …

类加载过程中几个重点执行顺序整理
类的加载过程: 1、 JVM会先去方法区中找有没有相应类的.class存在。如果有,就直接使用;如果没有,则把相关类的.class加载到方法区 2、 在.class加载到方法区时,会分为两部分加载:先加载非静态内容ÿ…

二叉树 2.0 -- 非递归遍历
二叉树递归遍历存在的问题 如果我们的二叉树只有左子树,而且树的高度还很深的时候,这个时候递归调用遍历的时候,栈帧空间开辟的较大,很可能造成栈溢出。但是我们一个程序中,为堆分配的空间要比栈大的多,这…

田忌赛马贪心算法_田忌赛马 贪心算法
算法实验课回顾田忌赛马问题描述:你一定听说过田忌赛马的故事吧?如果3匹马变成n匹(n<100),齐王仍然让他的马按照优到劣的顺序初赛,田忌可以按任意顺序选择他的赛马出赛。赢一局,田忌可以得到200两银子;输…