一、继承

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的,则在类体外也可以使用“ 派生类对象.基类名::函数名(参数)” 
的语法,也可用“ 派生类指针->基类名::函数名(参数)”的语法,同理被隐藏的数据成员也可以使用上述列举的方法访问。

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

最新文章

  1. 每天写点shell--命令行参数
  2. WPF MVVM框架下,VM界面写控件
  3. python 进程间共享数据 (三)
  4. Android 解压html压缩数据
  5. h.264 mvp求解过程
  6. java 异常处理机制及说明。
  7. mui学习链接
  8. JAVA流读取文件并保存数据
  9. 构建自定义docker镜像,上传至docker hub
  10. html禁止页面滚动
  11. python线程池(threadpool)模块使用笔记 .python 线程池使用推荐
  12. K - Find them, Catch them POJ - 1703 (带权并查集)
  13. Java面试题—初级(9)
  14. 【算法30】从数组中选择k组长度为m的子数组,要求其和最小
  15. TensorFlow Python3.7环境下的源码编译(三)编译
  16. 本机ip和127.0.0.1的区别
  17. (转)USB协议简介
  18. java使用链栈实现数制转换
  19. ansible初识二
  20. 从map中取出最大或最小value对应的key---多种写法

热门文章

  1. MYSQL 命令行导入导出
  2. HDU 4070 Phage War
  3. FZOJ2111:Min Number
  4. Unity 3D 文件导入出错
  5. Logistic Regression(逻辑回归)(一)基本原理
  6. C++学习之路—运算符重载(一)概念、方法及规则
  7. 如果一个Object对象可能是集合或者数组那么如何对其进行迭代
  8. javascript json格式解析方法
  9. 手机字段存储报错 :Warning Code : 1264 Out of range value for column &#39;buyer_tpl&#39; at row 1
  10. 不使用webview,用手机浏览器的android app