博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别...
阅读量:7282 次
发布时间:2019-06-30

本文共 3142 字,大约阅读时间需要 10 分钟。

一、继承

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_ = 
10;
        y_ = 
20;
        
//z_ = 30; error
    }
private:
    
int a_;
};
class PublicPublicInherit : 
public PublicInherit
{
public:
    
void Test()
    {
        y_ = 
20;
    }
};
class PrivateInherit : 
private Base
{
public:
    
void Test()
    {
        x_ = 
10;
        y_ = 
20;
        
//z_ = 30; error
    }
};
int main(
void)
{
    PublicInherit pub;
    pub.x_ = 
20;
    PrivateInherit pri;
    
//pri.x_ = 10; error
    
return 
0;
}

 

 

(五)、继承与重定义

对基类的数据成员的重定义

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

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_(
0), y_(
48)
    {
    }
    
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_(
0)
    {
    }
    
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_ = 
10;
    d.Base::x_ = 
20
//访问被隐藏的基类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 
0;
}

 

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

 

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

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

(2)函数名字相同;

(3)参数不同;

(4)virtual关键字可有可无。
覆盖(override)是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
隐藏(overwrite)(派生类与基类)
(1)不同的范围(分别位于派生类与基类);
(2)函数名与参数都相同,无virtual关键字
(3)函数名相同,参数不同,virtual可有可无
当隐藏发生时(实际上是继承了但不可见),如果在派生类的成员函数中想要调用基类的被隐藏函数,可以使用
“ 基类名::函数名(参数)”的语法形式,如果被隐藏的函数是public的,则在类体外也可以使用“ 派生类对象.基类名::函数名(参数)”  的语法,也可用“ 派生类指针->基类名::函数名(参数)”的语法,同理被隐藏的数据成员也可以使用上述列举的方法访问。
如果不属于上述的情况,则是一般的继承,则使用一般的访问语法即可。

 

 

 

你可能感兴趣的文章
选一个合适的Web前端编辑器
查看>>
我的友情链接
查看>>
RMI 两个端口
查看>>
查看eclipse使用的jre版本
查看>>
我的友情链接
查看>>
MySQL必知必会---过滤数据
查看>>
CCN课程究极笔记(上ccna课程记录的)
查看>>
wireshark grpc 客户端 发送报文
查看>>
MediaClock及音视频同步
查看>>
JavaScript事件大全
查看>>
Centos安装笔记
查看>>
Dubbo中暴露服务的过程解析
查看>>
android网络通信之socket教程实例汇总
查看>>
Confluence 6 管理协同编辑 - 修改你的 Synchrony 配置
查看>>
Confluence 6 应该如何在我的空间中组织内容
查看>>
Android事件分发机制
查看>>
shell不排序去重
查看>>
订阅号功能----音乐
查看>>
HTML-常用元素标签手册
查看>>
JS基础-DOM Event对象手册
查看>>