1、继承与派生

   继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一。简单的说,继承是指一个对象直接使用另一对象的属性和方法。继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程。C++中的继承关系就好比现实生活中的父子关系,继承一笔财产比白手起家要容易得多,原始类称为基类,继承类称为派生类,它们是类似于父亲和儿子的关系,所以也分别叫父类和子类。而子类又可以当成父类,被另外的类继承。继承的方式有三种分别为公有继承(public),保护继承(protect),私有继承(private)。
定义格式如下:

2、继承方式及访问属性

(1) 公有继承(public)

公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员对派生类是不可见的,也不能被这个派生类的子类所访问。

(2)私有继承(private)

私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。

(3)保护继承(protected)

保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然私有,且对派生类不可见。

  private能够对外部和子类保密,即除了成员所在的类本身可以访问之外,别的都不能直接访问。protected能够对外部保密,但允许子类直接访问这些成员。public、private和protected对成员数据或成员函数的保护程度可以用下表来描述:举个栗子:

 class Base    //父类
{
private:
int _priB;
protected:
int _proB;
public:
int _pubB;
} ;
class Derived: public Base //子类,继承自base,继承类型为公有继承
{
private:
int _d_pri;
protected:
int _d_pro;
public:
void funct()
{
int d;
d=_priB; //error:基类中私有成员在派生类中是不可见的
d=_proB; //ok: 基类的保护成员在派生类中为保护成员
d=_pubB; //ok: 基类的公共成员在派生类中为公共成员
}
int _d_pub;
} ;
总结:(1). public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用, 因为每个子类对象也都是一个父类对象。
class C :private Base //基类Base的派生类C(私有继承)
{
public:
void funct()
{
int c;
c=_priB; //error:基类中私有成员在派生类中是不可见的
c=_proB; //ok:基类的保护成员在派生类中为私有成员
c=_pubB; //ok:基类的公共成员在派生类中为私有成员
}
};
class E :protected Base //基类Base的派生类E(保护继承)
{
public:
void funct()
{
int e ;
e=_priB; //error:基类中私有成员在派生类中是不可见的
e=_proB; //ok:基类的保护成员在派生类中为保护成员
e=_pubB; //ok:基类的公共成员在派生类中为保护成员
}
};
总结:
(2). 基类的private成员 在派生类中是不能被访问的, 如果基类成员 不想在类外直接被访问, 但需要 在派生类中能访问, 就定义为protected。 可以看出保护成员 限定符是因继承才出现的。
(3). protected/private继承是一个实现继承, 基类的部分成员 并非完全成为子类接口 的一部分, 是 has-a 的关系原则, 所以非特殊情况下不会使用这两种继承关系, 在绝大多数的场景下使用的 都是公有继承。 私有继承以为这is-implemented-in-terms-of(是根据……实现的) 。 通常比组合(composition) 更低级, 但当一个派生类需要访问 基类保护成员 或需要重定义基类的虚函数时它就是合理的。
 int main()
{
int a;
D d;
a=D._priB; //error:公有继承基类中私有成员在派生类中是不可见的,对对象不可见
a=D._proB; //error:公有继承基类的保护成员在派生类中为保护成员,对对象不可见
a=D._pubB; //ok:公有继承基类的公共成员在派生类中为公共成员,对对象可见
C c;
a=c._priB; //error:私有继承基类中私有成员在派生类中是不可见的, 对对象不可见
a=c._proB; //error:私有继承基类的保护成员在派生类中为私有成员,对对象不可见
a=c._pubB; //error:私有继承基类的公共成员在派生类中为私有成员,对对象不可见
E e;
a=e._priB; //error:保护继承基类中私有成员在派生类中是不可见的, 对对象不可见
a=e._proB; //error:保护继承基类的保护成员在派生类中为保护成员,对对象不可见
a=e._pubB; //error:保护继承基类的公共成员在派生类中为保护成员,对对象不可见 return ;
}

(4)不管是哪种继承方式, 在派生类内部都可以访问基类的公有成员和保护成员 , 基类的私有成员存在但是在子类中不可见( 不能访问) 。
(5)使用关键字class时默认的继承方式是private, 使用struct时默认的继承方式是public, 不过最好显式的写出继承方式。
(6)在实际运用中一般使用都是public继承, 极少场景下才会使用protetced/private继承。

在struct继承中,如果没有显式给出继承类型,则默认的为public继承;在class继承中,如果没有显式给出继承类型,则默认的为private继承;

继承关系&访问限定符

注意:派生类需要添加自己的构造函数(下一篇会详细分析这些特性)

(1)创建派生类对象时,程序首先创建基类对象;

(2)要通过初始化表用基类的构造函数给继承过来的成员变量提供初始值;

(3)如果省略了基类的初始化表,程序会使用基类的默认构造函数;

(4)也应初始化派生类新增的数据成员;

(5)派生类对象过期时,首先调用派生类的析构,再调用基类的析构;

(6)派生类应根据需要添加自己的成员变量和方法;

3、基类与派生类的关系-指针或引用

(1)基类指针或引用可以在不进行显式类型转换的情况下指向或引用派生类对象,但是基类指针或引用只能调用基类的方法,无法调用派生类的方法,而派生类指针或引用是不能指向或引用基类对象的;

(2)参数为基类引用或指针的函数,也可以将派生类对象作为参数,这可以让基类对象使用派生类来初始化;

(3)这也可以将派生类赋值给基类 – 此时派生类的基类部分被复制给基类,将派生类对象赋值给基类对象,但这只涉及到基类的部分,派生类中的派生部分将被忽略掉,其实质是调用基类的赋值运算符 – 此函数参数为基类的引用;

(4)公有继承建立一种is-a 关系 – is-a-kind-of

  即派生类是基类的一种 – 只是比基类更特殊了一下而已,并非 is-like-a – 即没有比喻关系,派生类只能在基类的基础上添加属性,但是不能删除属性,并非 is-implenmented-as-a – 即没有实现关系 如数组可以用来实现栈,但是不能从Array派生出Stack类,而是将数组对象封装在栈里并非use-a – 即没有使用关系 – 可以通过友元或类来实现类之间的通信(使用)。public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。比如白马是马,香蕉是水果。

(5)protetced/private继承建立一种has-a 关系

  protetced/private继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是 has-a 的关系原则。午餐有香蕉。但是午餐不是香蕉。

C++中的类继承(1) 三种继承方式的更多相关文章

  1. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  2. C++继承(一) 三种继承方式

    继承定义 继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一. 继承就是不修改原有的类,直接利用原来的类的属性和方法并进行扩展.原来的类称为基类,继承的类称为派生类,他们的关系就像父子 ...

  3. python中关于类隐藏属性的三种处理方法

    关于隐藏属性 引子: 当类的属性或者类实例对象的属性隐藏的时候必须通过存取器方法来获取和设置这些隐藏的属性. 例如: def get_name(self,name):     #存取器方法 self. ...

  4. java中进程与线程的三种实现方式

    一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程. 进程:进程是指 ...

  5. C++的三种继承方式简述

    C++对父类(也称基类)的继承有三种方式,分别为:public继承.protected继承.private继承.三种继承方式的不同在于继承之后子类的成员函数的"可继承性质". 在说 ...

  6. JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  7. C++中的三种继承关系

    C++中的三种继承关系 先看类中声明成员时的三种访问权限 public : 可以被任意实体访问 protected : 只允许子类及本类的成员函数访问 private : 只允许本类的成员函数访问 在 ...

  8. js oop中的三种继承方法

    JS OOP 中的三种继承方法: 很多读者关于js opp的继承比较模糊,本文总结了oop中的三种继承方法,以助于读者进行区分. <继承使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方 ...

  9. C++中的三种继承public,protected,private

    ( c++默认class是private继承且class内的成员默认都是private struct 默认位public 继承,struct内成员默认是public  ) 三种访问权限 public: ...

随机推荐

  1. Oracle11G卸载教程

    用Oracle自带的卸载程序不能从根本上卸载Oracle,从而为下次的安装留下隐患,那么怎么才能完全卸载Oracle呢?那就是直接注册表清除,步骤如下: 1. 开始->设置->控制面板-& ...

  2. Couchbase 中的分布式储存

    Couchbase 是一个具有高性能.可扩展性和可 用性强的数据库引擎.它可以让开发人员通过 NoSQL 的键值存储(二进制或者JSON)或者使用 N1QL 的形式对数据进行操作(N1QL 是非常类似 ...

  3. Prince2是怎么考试的?想了解P2

    自己在项目管理培训的行业已经有了5年的时间,经历了很多的学员和企业,和他们交流的问题,话题也很多. 在前几年,对于项目经理来讲关注的很多是单项目管理的工具技术模板,谈论最多的是,进度延期,成本超支,范 ...

  4. abstract和interface的区别

    abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和inte ...

  5. 【解题报告】pojP1436 Horizontally Visible Segments

    http://poj.org/problem?id=1436 题目大意:有n条平行于x轴的线段,每条线段有y坐标,如果两条线段有一段x坐标数值相等,且中间没有其它线段阻隔,则称这两条线段"照 ...

  6. Ionic2开发笔记(2)创建子页面及其应用

    1. 当你第一次产生ionic2应用程序,这是生成的项目结构 ├── ├── config.xml      这包含配置应用程序的名称,和包名,将被用于我们的应用程序安装到一个实际的设备. ├── h ...

  7. Docker存储驱动之总览

    简介 本文会介绍Docker存储驱动的特性,别列出现在已经支持的存储驱动,最后,会介绍如果选型适合你的存储驱动. 可插拔的存储驱动架构 Docker的存储驱动架构是可插拔的,可以让你很方便的将适合你环 ...

  8. Hibernate写配置文件无提示信息解决

    把Hibernate的相关jar包引入工程后,在配置hibernate.cfg.xml时没有提示信息,对于开发人员来说,那么多标签,标签有那么多属性,全部都记住显然是不可能的,遇到这种情况是很头疼的事 ...

  9. Office 365 开发概览系列文章和教程

    Office 365 开发概览系列文章和教程 原文于2017年2月26日首发于LinkedIn,请参考链接 引子 之前我在Office 365技术社群(O萌)中跟大家提到,3月初适逢Visual St ...

  10. HNOI(湖南省选试题)——永无乡

    今天写了一道十分巧妙的数据结构题---永无乡 (看的题解......) 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 ...