继承与派生

一、什么是继承和派生

所谓继承就是从先辈处得到属性和行为特征。类的继承,是新的类从已有类那里得到已有的特性。从另一个角度来看这个问题,从已有类产生新类的过程就是类的派生。类的继承与派生机制允许程序员在保持原有类特性的基础上,进行更具体、更详细的修改和扩充。由原有的类产生新类时,新类便包含了原有类特征,同时也可以加入自己所特有的新特性。原有的类称为基类父类,产生的新类称为派生类子类

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。

当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。

单继承

class 派生类名:继承方式 基类名
{
派生类新定义成员
};

多继承

class 派生类名:继承方式1 基类1,继承方式2 基类2
{
派生类成员声明;
};

二、继承类型

当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承的方式规定了如何访问从基类继承的成员。当使用不同类型的继承时,遵循以下几个规则:

  • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有保护成员来访问。
  • 保护继承(protected): 当一个类派生自保护基类时,基类的公有保护成员将成为派生类的保护成员。
  • 私有继承(private):当一个类派生自私有基类时,基类的公有保护成员将成为派生类的私有成员。

三、实例

公有继承

基类成员访问属性 派生类成员访问属性
public public
protected protected
private 无法访问
#include "pch.h"
#include <iostream>
using namespace std;
class Point
{
public: void initP(float xx,float yy);
void Move(float xOff,float yOff);
float GetX() { return x; }
float GetY() { return y; }
private:
float x, y;
};
void Point::initP(float xx, float yy)
{
x = xx;
y = yy;
}
void Point::Move(float xOff, float yOff)
{
x = xOff;
y = yOff;
} class Rectangle : public Point
{
public:
void initR(float x, float y, float w, float h)
{
initP(x, y);
W = w;
H = h;
}
float GetW() { return W; }
float GetH() { return H; }
private:
float W, H;
}; int main()
{
Rectangle r;
r.initR(1,2,3,4);
r.Move(5,7);
cout << r.GetX() <<" "<< r.GetY() <<" "<< r.GetW() <<" "<< r.GetH() << endl;
}

运行截图

私有继承

基类成员访问属性 派生类成员访问属性
public private
protected private
private 无法访问
#include "pch.h"
#include <iostream>
using namespace std;
class Point
{
public: void initP(float xx,float yy);
void Move(float xOff,float yOff);
float GetX() { return x; }
float GetY() { return y; }
private:
float x, y;
};
void Point::initP(float xx, float yy)
{
x = xx;
y = yy;
}
void Point::Move(float xOff, float yOff)
{
x = xOff;
y = yOff;
} class Rectangle : private Point // 将上一段代码里的public改成了private
{
public:
void initR(float x, float y, float w, float h)
{
initP(x, y);
W = w;
H = h;
}
float GetW() { return W; }
float GetH() { return H; }
private:
float W, H;
}; int main()
{
Rectangle r;
r.initR(1,2,3,4);
r.Move(5,7);
cout << r.GetX() <<" "<< r.GetY() <<" "<< r.GetW() <<" "<< r.GetH() << endl;
}

运行截图

保护继承

基类成员访问属性 派生类成员访问属性
public protected
protected protected
private 无法访问
#include "pch.h"
#include <iostream>
using namespace std;
class Point
{
public: void initP(float xx,float yy);
void Move(float xOff,float yOff);
float GetX() { return x; }
float GetY() { return y; }
private:
float x, y;
};
void Point::initP(float xx, float yy)
{
x = xx;
y = yy;
}
void Point::Move(float xOff, float yOff)
{
x = xOff;
y = yOff;
} class Rectangle : protected Point //将第一段代码里的public改成protected
{
public:
void initR(float x, float y, float w, float h)
{
initP(x, y);
W = w;
H = h;
}
float GetW() { return W; }
float GetH() { return H; }
private:
float W, H;
}; int main()
{
Rectangle r;
r.initR(1,2,3,4);
r.Move(5,7);
cout << r.GetX() <<" "<< r.GetY() <<" "<< r.GetW() <<" "<< r.GetH() << endl;
}

运行截图

通过比较私有继承和保护继承可以看出,实际上在直接派生类中,所有成员的访问属性都是完全相同的。但是,如果派生类作为新的基类继续派生时,二者就会产生差别

第四次C++的更多相关文章

  1. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  2. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  3. 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户

    阅读目录 前言 怎么卖 领域服务的使用 回到现实 结语 一.前言 上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计.现在把剩余的“卖”这个动作给做了.这里提醒一下,正常情况下,我们的每一步业 ...

  4. 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)

    从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  5. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  6. “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)

    前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...

  7. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  8. HTML 事件(四) 模拟事件操作

    本篇主要介绍HTML DOM中事件的模拟操作. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4.  ...

  9. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  10. 带你实现开发者头条APP(四)---首页优化(加入design包)

    title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...

随机推荐

  1. 20190829 [ Night ] - 玻

    又考试 半集训真累…… 老帅哥露出会心的微笑.jpeg +------------+ | 寸 | | 土 分 | | 不 分 | | 让 必 | | 争 | +------------+ 考试过程: ...

  2. 小希的迷宫 HDU - 1272 (并查集)

    思路: 当图中的集合(连通子图)个数为1并且边数等于顶点数-1(即改图恰好为一棵生成树)时,输出Yes. 此题的坑:(1) 如果只输入0 0算作一组数据的话答案应该输出Yes (2) 输入数据可能并不 ...

  3. JavaScript 面试:什么是纯函数?

    原文:Eric Elliott  译文:众成翻译 www.zcfy.cc/article/master-the-javascript-interview-what-is-a-pure-function ...

  4. CesiumLab V1.2 新功能 倾斜数据处理

    一转眼又是一周的时间,我们的实验室功能又强大了. 照旧我们先放毒,放图,图,太晚了,字都敲不到一起了   lod以及包围盒   大雁塔实例,按楼层单体化   倾斜数据处理参数设置 简单介绍一下 Ces ...

  5. 2019.10.22 csp-s模拟测试82 反思总结

    重来重来,刚刚就当什么都没发生 今天的题属实有些迷惑,各种意义上…总之都很有难度吧.不满归不满,这套题的确不是什么没有意义的题目. 为了考验自己的学习能力记忆力,决定不写题解,扔个代码完事了 其实是懒 ...

  6. 通过inputSplit分片size控制map数目

    前言:在具体执行Hadoop程序的时候,我们要根据不同的情况来设置Map的个数.除了设置固定的每个节点上可运行的最大map个数外,我们还需要控制真正执行Map操作的任务个数. 1.如何控制实际运行的m ...

  7. 【CRT相关配置】

    1.选项——会话选项 2.回话调整如下: 3.日志文件记录保存,即保存所有输入的命令 文件名:%S-%T-%M-%D.txt,表示每天会存放到一个文件 选择:在连接上启动记录 和  追加到文件

  8. QT_获取运行进程所在目录路径_1

    QString getProcessPathForWin(int idProcess) { #ifdef Q_OS_WIN // access process path WCHAR name[]; Z ...

  9. Hdu 4751(2-SAT)

    题目链接 Divide Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  10. update批量更新某一列成其它列对应的值【原】

    update批量更新某一列成其它列对应的值 postgresql 标准sql语句 update AA set name = BB.name , AA.sex = BB.sex from BB wher ...