一、继承

C++很重要的一个特征就是代码重用。在C语言中重用代码的方式就是拷贝代码、修改代码。C++可以用继承或组合的方式来重用。通过组合或继承现有的的类来创建新类,而不是重新创建它们。

继承是使用已经编写好的类来创建新类,新的类具有原有类的所有属性和操作,也可以在原有类的基础上作一些修改和增补。
新类称为派生类或子类,原有类称为基类或父类
派生类是基类的具体化

(一)、派生类的声明语法为:
class 派生类名 : 继承方式  基类名
{
           派生类新增成员的声明;
}

(二)、公有/私有/保护成员

在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。
在关键字private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。
在关键字protected后面声明,与private类似,其差别表现在继承与派生时对派生类的影响不同

(三)、公有/私有/保护继承

(四)、接口继承与实现继承

我们将类的公有成员函数称为接口。
公有继承,基类的公有成员函数在派生类中仍然是公有的,换句话说是基类的接口成为了派生类的接口,因而将它称为接口继承。
实现继承,对于私有、保护继承,派生类不继承基类的接口。派生类将不再支持基类的公有接口,它希望能重用基类的实现而已,因而将它称为实现继承。

 C++ Code 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

 
#include <iostream>


using 
namespace std;

class Base

{


public:

    
int x_;


protected:

    
int y_;


private:

    
int z_;

};

class PublicInherit : 
public Base

{


public:

    
void Test()

    {

        x_ = 
;

        y_ = 
;

        
//z_ = 30; error
    }


private:

    
int a_;

};

class PublicPublicInherit : 
public PublicInherit

{


public:

    
void Test()

    {

        y_ = 
;

    }

};

class PrivateInherit : 
private Base

{


public:

    
void Test()

    {

        x_ = 
;

        y_ = 
;

        
//z_ = 30; error
    }

};

int main(
void)

{

    PublicInherit pub;

    pub.x_ = 
;

PrivateInherit pri;

    
//pri.x_ = 10; error
    
return 
;

}

(五)、继承与重定义

对基类的数据成员的重定义
对基类成员函数的重定义分为两种

overwrite(隐藏)

override(覆盖)

(六)、继承与组合

无论是继承与组合本质上都是把子对象放在新类型中,两者都是使用构造函数的初始化列表去构造这些子对象。
组合通中是在希望新类内部具有已存在的类的功能时使用,而不是希望已存在类作为它的接口。组合通过嵌入一个对象以实现新类的功能,而新类用户看到的是新定义的接口,而不是来自老类的接口。(has-a)
如果希望新类与已存在的类有相同的接口(在这基础上可以增加自己的成员)。这时候需要用继承,也称为子类型化。(is-a)

 C++ Code 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

 
#include <iostream>


using 
namespace std;

class Base

{


public:

    Base() : x_(
), y_(
)

    {

}

    
int GetBaseX() 
const

    {

        
return x_;

    }

int GetBaseY() 
const

    {

        
return y_;

    }

    
void Show()

    {

        cout << 
"Base::Show ..." << endl;

    }

    
int x_;


private:

    
int y_; 
//继承后无法被直接访问,可通过GetBaseY访问
};

class Derived : 
public Base

{


public:

    Derived() : x_(
)

    {

}

    
int GetDerivedX() 
const

    {

        
return x_;

    }

    
void Show(
int n)
//与下面的show 构成重载,基类的show被隐藏
    {

        cout << 
"Derived::Show " << n << endl;

    }

void Show()

    {

        cout << 
"Derived::Show ..." << endl;

    }

    
int x_; 
//重定义x_,基类的x_被隐藏
};

//组合关系

class Test

{


public:

    Base b_;

    
int x_;

};

int main(
void)

{

    Derived d;

    d.x_ = 
;

    d.Base::x_ = 

//访问被隐藏的基类x_;
    cout << d.GetBaseX() << endl;

    cout << d.GetDerivedX() << endl;

    cout << d.GetBaseY() << endl;

d.Show();

    d.Base::Show();
//访问被隐藏的基类show

cout << 
sizeof(Derived) << endl;

    cout << 
sizeof(Test) << endl;

return 
;

}

下面总结一下overload/overwrite/override 之间的区别:

成员函数被重载(overload)的特征:


(1)相同的范围(在同一个类中);


(2)函数名字相同;


(3)参数不同;


(4)virtual关键字可有可无。


覆盖(override)是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual关键字。

隐藏(overwrite)(派生类与基类)

(1)不同的范围(分别位于派生类与基类);

(2)函数名与参数都相同,无virtual关键字

(3)函数名相同,参数不同,virtual可有可无

当隐藏发生时(实际上是继承了但不可见),如果在派生类的成员函数中想要调用基类的被隐藏函数,可以使用
“ 基类名::函数名(参数)”的语法形式,如果被隐藏的函数是public的,则在类体外也可以使用“ 派生类对象.基类名::函数名(参数)” 
的语法,也可用“ 派生类指针->基类名::函数名(参数)”的语法,同理被隐藏的数据成员也可以使用上述列举的方法访问。

如果不属于上述的情况,则是一般的继承,则使用一般的访问语法即可。

从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别的更多相关文章

  1. 公有/私有/保护继承、overload/overwrite/override之间的区别

    一.继承 C++很重要的一个特征就是代码重用.在C语言中重用代码的方式就是拷贝代码.修改代码.C++可以用继承或组合的方式来重用.通过组合或继承现有的的类来创建新类,而不是重新创建它们. 继承是使用已 ...

  2. js对象的继承以及公有私有属性的定义和读写

    最近想写一些js工具,有些方面需要用到面向对象的方法,比如继承父类属性和方法.通过私有化隐藏某些对象的属性等,因为没有系统的学习js,所以不知道怎么做,觉得很伤脑筋. 今天受到技术群里朋友的提示,并查 ...

  3. 从零开始学C++之RTTI、dynamic_cast、typeid、类与类之间的关系uml

    一.RTTI Run-time type information (RTTI) is a mechanism that allows the type of an object to be deter ...

  4. C++继承:公有,私有,保护

    前言 无论是在平时学习中还是还做项目之时,主要用到的继承都是 public 公有继承,因此,对protected private两者继承都不大了解! 今天,在看<Effective C++ 3e ...

  5. C++学习笔记14,private/protected/public继承,私有继承,保护继承,公有继承(五)(总结)

    各种继承方式: 特征 公有继承 保护继承 私有继承 公有成员变为 派生类的公有成员 派生类的保护成员 派生类的私有成员 保护成员变为 派生类的保护成员 派生类的保护成员 派生类的私有成员 私有成员变为 ...

  6. C++ 中私有继承、保护继承与公有继承

    区别 下面通过一个示例来介绍三种继承的区别. 定义一个基类(假设为一个快退休的富豪): class RichMan { public: RichMan(); ~RichMan(); int m_com ...

  7. 从零开始学 Web 之 JS 高级(二)原型链,原型的继承

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  8. 从零开始学Kotlin-类的继承(6)

    从零开始学Kotlin基础篇系列文章 Kotlin中的超类Any Kotlin 中所有类都继承超类 Any 类 class demo6 //默认继承超类Any class demo6 : Any() ...

  9. C++中公有继承、保护继承、私有继承的区别

    公有继承时基类中各成员属性保持不变,基类中private成员被隐藏.派生类的成员只能访问基类中的public/protected成员,而不能访问private成员:派生类的对象只能访问基类中的publ ...

随机推荐

  1. sql server日期字段值的比较

    sql server中对日期字段值的比较 sql server中对日期字段的比较方式有多种,介绍几种常用的方式:用northwind库中的employees表作为用例表.1.between...and ...

  2. QFrame好像是万能的(可以随意画线,或者图片,放在其它元素之间做点缀,还可OnClick)

    QFrame *fr2=new QFrame(this); fr2->setGeometry(0,140,90,40); fr2->setStyleSheet("backgrou ...

  3. C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...

  4. EL表达式(1)

    JSP页面中支持使用EL表达式,EL全名为Expression Language.EL表达式的主要作用有: ① 获取数据: ② 执行运算: ③ 使用EL表达式的11大隐式对象: ④ 调用Java方法. ...

  5. 关于WM_ERASEBKGND和WM_PAINT的深刻理解

    一直以来,对于WM_PAINT和WM_ERASEBKGND消息不是很清楚,从书上和网上找了很多资料,大体上有以下几点说法:1>WM_PAINT先产生,WM_ERASEBKGND后产生 2.WM_ ...

  6. 红眼技术博客 » redis连接池红眼技术博客 » redis连接池

    红眼技术博客 » redis连接池 redis连接池

  7. Lucene.Net 2.3.1开发介绍 —— 二、分词(三)

    原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关 ...

  8. Android菜鸟的成长笔记(4)——你真的理解了吗?

    原文:Android菜鸟的成长笔记(4)--你真的理解了吗? 在上一篇中我们查看了QQ的apk源文件中的布局结构,并仿照QQ完成了我们第一个应用的界面,详细请看<Android菜鸟的成长笔记&g ...

  9. adb 之android的神器am

    am命令,am全称activity manager,你能使用am去模拟各种系统的行为,例如去启动一个activity,强制停止进程,发送广播进程,修改设备屏幕属性等等 命令窗口通过adb shell ...

  10. 网络数据(socket)传输总结

    环境限定:TCP/IP下的socket网络传输:C/C++开发语言,32/64位机. 目前有两种方式对数据进行传输:1)字符流形式,即将数据用字符串表示:2)结构型方式,即将数据按类型直接传输. 1) ...