您的位置:首页 > 编程语言 > C语言/C++

C++ 多态之继承2-继承的相关基础

2015-12-21 11:22 543 查看
之前我们讲了一下关于继承的一些抽象概念,现在我们来聊聊如何在c++中使用继承。

在c++中,继承发生在两个类之间。当一个类从另外一个继承,这个派生类将会继承基类的变量(variables)以及函数(functions)。这些变量以及函数变成了派生类的一部分。

A Person base class

如下是一个简单的基类(人):

#include <string>
class Person
{
public:
std::string m_strName;
int m_nAge;
bool m_bIsMale;

std::string GetName() { return m_strName; }
int GetAge() { return m_nAge; }
bool IsMale() { return m_bIsMale; }

Person(std::string strName = "", int nAge = 0, bool bIsMale = false)
: m_strName(strName), m_nAge(nAge), m_bIsMale(bIsMale)
{
}
};
这个基类包含了一些人的一些信息,如名字(name),年龄(age),性别(sex).需要注意的两点是.首先,我们仅仅是定义了所有人都共有的的属性,它能被所有人复用。其次,我们将所有的变量和函数设置为公有(public),仅仅是为了简化这个例子,通常情况下,应该讲变量设置为私有(private)。

 A BaseballPlayer derived class

class BaseballPlayer
{
public:
double m_dBattingAverage;
int m_nHomeRuns;
};
注意到它并没有包含棒球运动员的姓名,年龄以及性别。我们可以添加一些变量来直接保存这些信息,但是我们已经定义了一个通用的Person类,所有我们只需要简单的复用它。

逻辑上,我们知道棒球运动员和人有一些关系。需要弄清楚的是:a baseball player “has a” person, 还是 “is-a” person?显而易见,a baseball player
"is-a" person,所有baseball player 类使用继承而不是组合。
要继承Person类,语法上很简单。在声明完BaseballPlayer类后,加上关键字“public”,然后是我们希望继承的类。这称为共有继承,在后面我们会讲更多关于共有继承。

// BaseballPlayer publicly inheriting Person
class BaseballPlayer : public Person
{
public:
double m_dBattingAverage;
int m_nHomeRuns;

BaseballPlayer(double dBattingAverage = 0.0, int nHomeRuns = 0)
: m_dBattingAverage(dBattingAverage), m_nHomeRuns(nHomeRuns)
{
}
};


推导图来表示继承,如下:



当BaseballPlayer继承与Person,BaseballPlayer会自动从Person得到函数和变量。因此,BaseballPlayer对象会有5个成员变量(m_dBattingAverage
and m_nHomeRuns from BaseballPlayer, and m_strName, m_nAge, and m_bIsMale from Person)。

通过下面的代码很容易验证这点:

#include <iostream>
int main()
{
// Create a new BaseballPlayer object
BaseballPlayer cJoe;
// Assign it a name (we can do this directly because m_strName is public)
cJoe.m_strName = "Joe";
// Print out the name
std::cout << cJoe.GetName() << std::endl;

return 0;
}
结果为:Joe

An Employee
derived class


下面是另外一个继承于Person的类,称为Employee类(员工类)。一个员工
“is-a” 人,所以使用继承是合适的。

// Employee publicly inherits from Person
class Employee: public Person
{
public:
std::string m_strEmployerName;
double m_dHourlySalary;
long m_lEmployeeID;

Employee(std::string strEmployerName, double dHourlySalary, long lEmployeeID)
: m_strEmployerName(strEmployerName), m_dHourlySalary(dHourlySalary),
m_lEmployeeID(lEmployeeID)
{
}

double GetHourlySalary() { return m_dHourlySalary; }
void PrintNameAndSalary()
{
std::cout << m_strName << ": " << m_dHourlySalary << std::endl;
}
};
Employee 从Person继承了m_strName, m_nAge, m_bIsMale以及3个访问函数,并且添加了3个成员变量和自己的成员函数。注意的是成员函数PrintNameAndSalary同时使用了Employee自己的成员变量以及基类Person的成员变量。

派生表如下:



需要注意的是BaseballPlayer和Employee没有任何直接的联系,即使他们都继承了Person。

     Inheritance chains(继承链)

也有可能一个基类是另外一个类的派生类,即使如此也没什么值得特殊注意的,所有处理都按照之前的例子。

例如,一个公司管理人类(Supervisor),管理者也是员工,同样是一个人。如下:

class Supervisor: public Employee
{
public:
// This Supervisor can oversee a max of 5 employees
int m_nOverseesIDs[5];
};
派生表如下:



所有Supervisor对象继承了Employee的变量和函数,并且添加了自己的变量m_nOverseesIDs.

通过构造这样的继承链,我们能创建可重用类的集合,它们具有一般性(顶层),并在每个层面的继承上逐步变得更具体。

总结

从一个基类继承意味着我们不必要重新定义基类中的相关信息。自动获得基类的成员变量和成员函数,然后简单的添加我们需要的额外的成员函数和变量。这样不仅能节省工作,也意味着如果我们更新基类(添加新函数以及bug修复),所有的派生类将会自动继承这些修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: