C++ 面向对象的三个特点--继承与封装(一)
面试的时候经常会有很多概念性的东西,许久不用都会很生疏,特意整理一下方便自己以后不记得了可以查看一下,也顺便帮助自己复习一下。
概念
继承是面向对象程序设计的一个重要特性,它允许在既有类的基础上创建新的类,新类可以从一个或者是多个既有类中继承函数和数据,还可以重新定义或加入新的数据和函数。
基类成员在派生类中的访问属性归纳
我们了解类的成员可以有public、protected、private三种访问属性,类的自身成员可以访问类中的任何成员,但是通过对象访问的话,就只能访问类的public(公有)成员。
类的继承方式有public(公有继承)、protected(保护继承)、private(私有继承)。
在派生类中,基类成员的访问属性可以归纳为四种:不可直接访问,public,protected,private。
|
在基类中的访问属性 |
继承方式 |
在派生类中的访问属性 |
|
private |
public |
不可直接访问 |
|
private |
private |
不可直接访问 |
|
private |
protected |
不可直接访问 |
|
protected |
public |
protected |
|
protected |
private |
private |
|
protected |
protected |
protected |
|
public |
public |
public |
|
public |
private |
private |
|
public |
protected |
protected |
归纳一下就是:
(1). 基类的私有成员
无论是那种继承方式,基类的私有成员都不允许派生类继承。也就是派生类中不可直接访问的。
(2). 基类的保护成员
公有继承时,基类中得所有公有成员在派生类中以保护成员的身份出现。
保护继承时,基类中得所有保护成员在派生类中以保护成员的身份出现。
私有继承时,基类中得所有私有成员在派生类中以私有成员的身份出现。
(3). 基类的公有成员
公有继承时,基类中得所有公有成员在派生类中以公有成员的身份出现。
保护继承时,基类中得所有保护成员在派生类中以保护成员的身份出现。
私有继承时,基类中得所有私有成员在派生类中以私有成员的身份出现。
派生类对基类成员的访问规则
我们都知道,派生类对基类的访问形式主要有以下两种方式:(1).内部访问,有派生类新增的成员对基类继承过来的成员进行访问。(2).对象访问,在派生类的外部,通过定义派生类的对象来对基类继承来得成员进行访问。
那我们来分析三种继承方式下面,派生类对基类的访问规则。
i. 私有继承的访问规则
|
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
|
内部访问 |
不可访问 |
可以访问 |
可以访问 |
|
对象访问 |
不可访问 |
不可访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
//基类
class Base
{
public:
Base(int a, int b, int c): x(a),y(b),z(c)
{}
virtual ~Base(void); int x;
void printX()
{
printZ(); // 间接的访问基类的private成员
printf("X = %d\n", x);
} protected:
int y;
void printY()
{
printf("Y = %d\n", y);
} private:
int z;
void printZ()
{
printf("Z = %d\n", z);
}
}; //派生类
#include "base.h" class Derivel :
private Base
{
public:
Derivel(int a, int b, int c):Base(a,b,c)
{}
virtual ~Derivel(void); void show()
{
printX(); // 正确,基类的公有成员,派生类内部访问可能
printY(); // 正确,基类的保护成员,派生类内部访问可能
printZ(); // 错误,基类的私有成员,派生类不能内部访问
}
}; // main
#include "Base.h"
#include "Derivel.h" int _tmain(int argc, _TCHAR* argv[])
{
Derivel a(,,); a.printX();
// 错误,基类的公有成员,私有继承后作为派生类的私有成员,不能外部访问
a.printY();
// 错误,基类的保护成员,私有继承后作为派生类的私有成员,不能外部访问
a.printZ();
// 错误,基类的私有成员,私有继承后作为派生类的私有成员,不能外部访问
64 a.show();
return ;
}
总结:
当类的继承方式为私有继承的时候,基类的public和protected成员被继承后作为派生类的私有成员。在类的外部通过派生类的对象无法访问,但在派生类的内部是可以直接访问的。基类的private成员在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。如果你想访问的话,可以通过基类提供的public成员函数间接访问。
ii. 公有继承的访问规则
|
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
|
内部访问 |
不可访问 |
可以访问 |
可以访问 |
|
对象访问 |
不可访问 |
可以访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
//基类
class Base
{
public:
Base(int a, int b, int c): x(a),y(b),z(c)
{}
virtual ~Base(void); int x;
void printX()
{
printZ(); // 间接的访问基类的private成员
printf("X = %d\n", x);
} protected:
int y;
void printY()
{
printf("Y = %d\n", y);
} private:
int z;
void printZ()
{
printf("Z = %d\n", z);
}
}; //派生类
#include "base.h" class Derivel :
public Base
{
public:
Derivel(int a, int b, int c):Base(a,b,c)
{}
virtual ~Derivel(void); void show()
{
printX(); // 正确,基类的公有成员,派生类内部访问可能
printY(); // 正确,基类的保护成员,派生类内部访问可能
printZ(); // 错误,基类的私有成员,派生类不能内部访问
}
}; // main
#include "Base.h"
#include "Derivel.h"
int _tmain(int argc, _TCHAR* argv[])
{
Derivel a(,,);
a.printX();
// 正确,基类的公有成员,公有继承后作为派生类的公有成员,可以外部访问
a.printY();
// 错误,基类的保护成员,公有继承后作为派生类的保护成员,不能外部访问
a.printZ();
// 错误,基类的私有成员,公有继承后作为派生类的私有成员,不能外部访问
a.show();
return ;
}
总结:
当类的继承方式为公有继承的时候,基类的public成员被继承后作为派生类的公有成员。在类的外部通过派生类的对象和派生类的内部都可以直接访问。基类的protected成员被继承后作为派生类的保护成员,在类的外部通过派生类的对象不能访问,只能在派生类的内部访问。基类的private成员被继承后作为派生类的私有成员,在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。
iii. 保护继承的访问规则
|
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
|
内部访问 |
不可访问 |
可以访问 |
可以访问 |
|
对象访问 |
不可访问 |
不可访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
1 // 基类
2 class Base
3 {
4 public:
5 Base(int a, int b, int c): x(a),y(b),z(c)
6 {}
7 virtual ~Base(void);
8
9 int x;
10 void printX()
11 {
12 printZ(); // 间接的访问基类的private成员
13 printf("X = %d\n", x);
14 }
15
16 protected:
17 int y;
18 void printY()
19 {
20 printf("Y = %d\n", y);
21 }
22
23 private:
24 int z;
25 void printZ()
26 {
27 printf("Z = %d\n", z);
28 }
29 };
30
31 // 派生类
32 #include "base.h"
33
34 class Derivel :
35 protected Base
36 {
37 public:
38 Derivel(int a, int b, int c):Base(a,b,c)
39 {}
40 virtual ~Derivel(void);
41
42 void show()
43 {
44 printX(); // 正确,基类的公有成员,派生类内部访问可能
45 printY(); // 正确,基类的保护成员,派生类内部访问可能
46 printZ(); // 错误,基类的私有成员,派生类不能内部访问
47 }
48 };
49
50 // main
51 #include "Base.h"
52 #include "Derivel.h"
53
54 int _tmain(int argc, _TCHAR* argv[])
55 {
56 Derivel a(1,2,3);
57 a.printX();
58 // 错误,基类的公有成员,保护继承后作为派生类的保护成员,不能外部访问
59 a.printY();
60 // 错误,基类的保护成员,保护继承后作为派生类的保护成员,不能外部访问
61 a.printZ();
62 // 错误,基类的私有成员,保护继承后作为派生类的私有成员,不能外部访问
63 a.show();
64 return 0;
65 }
总结:
当类的继承方式为保护继承的时候,基类的public成员被继承后作为派生类的保护成员。在类的外部通过派生类的对象不能访问,在派生类的内部可以直接访问。基类的protected成员被继承后作为派生类的保护成员,在类的外部通过派生类的对象不能访问,只能在派生类的内部访问。基类的private成员被继承后作为派生类的私有成员,在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。
C++ 面向对象的三个特点--继承与封装(一)的更多相关文章
- C++ 面向对象的三个特点--继承与封装(二)
顺着上一篇的内容,我们继续来了解继承的基本知识. 派生类的构造函数和析构函数 派生类继承了基类的成员,但是不能继承基类的构造函数和析构函数,首先,我们了解构造函数和析构函数的执行顺序是当我们创建一个派 ...
- python面向对象(三)之继承
继承 介绍 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力.继承即常说的is-a关系.子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承 ...
- Python面向对象之:三大特性:继承,封装,多态以及类的约束
前言: python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情 ...
- 关于JS面向对象、设计模式、以及继承的问题总结
1.对象:JS中万物皆对象,它是一个泛指 类:对象的具体的细分 (物以类聚,人与群分.具有相同属性和方法的实例的一个集合总称) 实例:某一个类别中具体的一个事物 对象是一个抽象的概念,类似于我们的自然 ...
- javascript面向对象系列第三篇——实现继承的3种形式
× 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...
- python 面向对象专题(三):继承
目录 Python面向对象03 /继承 1. 初识继承 2. 单继承 3. 多继承 4. 总结 1. 初识继承 概念:专业角度:如果B类继承A类,B类就称为子类,派生类,A类就称为父类,超类,基类 种 ...
- 荒芜的周六-PHP之面向对象(三)
hi 又是开森的周六了.积攒的两周的衣服,终于是差不多洗完了.大下午的才来学点东西~~ 1.PHP面向对象(三) 四.OOP的高级实践 4.3 Static-静态成员 <?phpdate_def ...
- OOP三个基本特征:封装、继承、多态
面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...
- C++编程之面向对象的三个基本特征
面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...
随机推荐
- 批量Ping IP
刚刚接触Python 想做点什么 听说Python 在网络方便很厉害 后来总结如下: 第一:发现公司都固定IP 每次新来同事都要猜一个没有人用的IP 很费劲 第二:我们公司有的IP可以上QQ 有的不 ...
- 向上下左右不间断无缝滚动图片的效果(兼容火狐和IE)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)
本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...
- 几种图片下载lib对比
- On Caching and Evangelizing SQL
http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51asktom-453438.html Our technologist ...
- linux下批量查找/替换文本内容
一般在本地电脑上批量替换文本有许多工具可以做到,比如sublime text ,但大多服务器上都是无图形界面的,为此收集了几条针对linux命令行 实现批量替换文本内容的命令: 1.批量查找某个目下文 ...
- 如何让DevExpress TreeList的每个结点高亮显示?
概述:如何让DevExpress TreeList的每个节点高亮显示? 如何让DXperience TreeList的每个节点高亮显示? 效果如下: private void treeList1_Cu ...
- Base64 算法原理,以及编码、解码【加密、解密】 介绍
Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用 ...
- 【eoe 6】ActionBar的使用
一. Action Bar 一般位于屏幕顶部,包括四个可操作区域: 应用图标或LOGO区域,用于视图控制的Spinner下拉菜单或TAB控件区域, Action button(也称为Action It ...
- lucene.net的一个动态更新类
工作的需要,需要对于lucene.net索引即时的更新,毕竟lucene.net的索引重建的话比较慢,数据量大的时候建下要几天,所以就写个了缓冲类来解决即时的更新的问题,其实还是比较简单的. 大体上的 ...