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++编程之面向对象的三个基本特征
面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...
随机推荐
- Asp.net Request方法获取客户端的信息
Response.Write("客户端计算机名:" + Request.UserHostName + "<BR />"); Response.Wri ...
- Oracle数据库入门——常用的数据字典
一.oracle数据字典主要由以下几种视图构成:1.user视图以user_为前缀,用来记录用户对象的信息 2.all视图以all_为前缀,用来记录用户对象的信息及被授权访问的对象信息 3.dba视图 ...
- EDM备忘录:触发式邮件订阅和退订功能介绍
一般来说,有触发式邮件订阅和退订功能是邮件模板设计中必不可少的两项功能,下面博主为大家介绍一下. 若客户在订阅后不想再收到这类邮件即可选择退订,将不再收到该IP地址的推广邮件,避免客户在继续收到这类邮 ...
- MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)
转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...
- tengine-2.1.0 + GraphicsMagick-1.3.20
export LUAJIT_LIB=/usr/local/libexport LUAJIT_INC=/usr/local/include/luajit-2.0/./configure --prefix ...
- 【转】每个人应该知道的NVelocity用法
NVelocity是一个基于.NET的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象.从而使得界面设 ...
- Win7下安装git
1.下载并安装git for windows版本:msysgit http://msysgit.github.com/ 成功安装后,即可使用了,右键一个目录后可以看到菜单选项: 选择Git Gui ...
- Python Django 开发 2 数据库
一半教程用的Django都是1.8以前的版本,导致跟我用的1.8.2的版本用法有些出入,所以只能自己去官网看文档,以下一下是看官方文档而理解的,英语渣渣,可能会有理解有误的地方 先记录下如何查看dja ...
- 发布大幅重构优化的 TouchVG 1.0.2
发布大幅重构优化的 TouchVG 1.0.2,支持SVG.多模块扩展结构,欢迎评阅改进.提交pull request. https://github.com/rhcad/touchvg 关于 Tou ...
- 代码演示 .NET 4.5 自带的 ReadonlyCollection 的使用
代码如下: 1. using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...