第3章 感受(一)——3.9. Hello object 派生版

[回到目录]
白话C++

3.9. Hello object 派生版

当我写完前一小节时,我听到很多读者在喊“志玲!志玲!”。是啊,有人对我用xiaoA和xiaoB这样两个没有创意的人物来演绎“Hello Object 成员版”表示抗议:“志玲上哪儿去了呢?”

关键是,如果让“志玲”上场,那么我们就需要开始面对一个问题:既然,我们对“志玲”的问好都要与众不同,那么,她的自我介绍,难道就不能来点变化?

3.9.1. 使用分支

有了“Hello world 分支版”的经验,读者可以立即操刀了。那就让我们新建一个控制台应用程序,取名为“HelloOODerive”。 并且如有需要,请打开向导创建的main.cpp文件,并确保将它的文件编码改为“系统默认”。

最初代码来源于上一小节,修改起来也不困难:

struct Person
{
//此处省略:构造与析构函数

void Introduction()
{
020 if (name == "志玲")
021 {
022 cout << "大家好,我是志玲,请多多关照!" << endl;
023 }
024 else
025 {
026 cout << "Hi, my name is " << name << "." << endl;
027 }
}

std::string name;
};

代码的逻辑是,如果名字是“志玲”,就用特别的方法输出自我介绍(022行),否则照旧(026行)。

立即修改main函数中,原有的xiaoB全部换成zhiLing;并且将名字修改成我们希望的“志玲”。

〖重要〗:让代码符号和你的思想一致

本 例中,变量名称并不影响程序运行结果。也就是说,就算你不把变量名“xiaoB”全部替换成“zhiLing”,只要你将xiaoB->name 赋值为 “志玲”,程序的结果也一样是我们想要的。但是!这种做法是不受欢迎的。代码不仅仅用来编译,当代码需要人来阅读时,代码符号,比如变量的取名就相当重 要。且记:请让代码符号在字面上所表述的出来的意思,和你的真实思想尽量一致。

 

int main()
{
Person xiaoA;
xiaoA.name = "Xiao A";

038 Person *zhiLing = new Person;
039 zhiLing->name = "志玲";

xiaoA.Introduction();
042 zhiLing->Introduction();

044 delete zhiLing;

return 0;
}

请编译、并运行当前程序,检查结果是否正确。

3.9.2. 为何派生

针对最初的需求,上面的代码已经是完美的实现。现在我们要站在一个更高的位置重新考虑需求,这个需求的基本出发点是——

“‘志玲’她不是一个人,她是一类人——美人。”

展开地讲,只要是一个美人,就让她使用美人专用的自我介绍方法。不管这个美人名字是“志玲”、“美玲”、还是“嘉玲”……名字并不重要,名字再动听,也不一定就代表你是美人——比如“芙蓉”。

我们对前例最不满意的地方就是,它通过一个人的名字来判断是否美人,这是愚蠢的做法。更合理的做法是:属于“美人”类的对象才是美人。

 

〖课堂作业〗:用老办法实现对多个美女姓名的判断

请大家在前例代码的基础上,实现程序对:“志玲”、“嘉玲”、“美玲”三种情况的判断,当条件成立时,可以统一输出“大家好,我是XXX,请多多关照”。XXX代表真实名字。

 

3.9.3. 如何派生

既然,“‘志玲’她不是一个人,她是一类人——美人”,那么我们现在就来定义“美人类”吧。

“美人类”是一个什么类别呢?“美人类”是“人类”的一个子类别。人有美的,也有不美的,比如作者我,但不管美或不美的,反正都是人。

用一张图表示派生关系:

TODO:(UML图~~~~~~~)

在C++中,用来表示“B类是A类的一个子类”这个概念,就称为“派生”。B类是A类的一个子类,用C++的行话讲,就是:B类派生自A类。具体语法是:

struct 派生类 : public 基类
{
};

对应于美人类,那就是:美人类派生自人类。

struct Beauty : public Person
{
};

〖重要〗:理解“is a ……”原则

B 派生自A,那么,B的对象在逻辑上就应该是一个A对象。违反了这一原则,就说明你在A、B的关系在设计上有问题。今后我们在考虑是否让某个类派生自另一个 类时,都要首先问一下这个问题。比如今天,我们可以肯定地说: “人不一定是美人,但美人一定是人”。那就说明我们的设计,问题不大。

 

3.9.4. 定义“美人类”

在本设计中,“美人”和“人”的主要区别就是她们的自我介绍方式不同,所以我们要在美人类中重写一个Introduction函数。

在原有代码的“Person{……};”之后,插入Beauty的定义:

struct Beauty : public Person
{
void Introduction()
{
cout << "大家好,我是美女: " << name << ",请多多关照!" << endl;
}
};

基类Person的Introduction不再需要通过名字来判断一个人是否美女的,因此,简单了很多:

struct Person
{
//此处略去构造与析构函数

void Introduction()
{
cout << "Hi, my name is " << name << "." << endl;
}

std::string name;
};

3.9.5. 使用“美人类”

直接看main函数的修改结果:

int main()
{
Person xiaoA;
xiaoA.name = "Xiao A";

039 Beauty* zhiLing = new Beauty;
zhiLing->name = "志玲";

//新加一个美女:
043 Beauty jiaLing;
jiaLing.name = "嘉玲";

xiaoA.Introduction();
zhiLing->Introduction();
048 jiaLing.Introduction();

delete zhiLing;

return 0;
}

039行,zhiLing由原来的“Person”类改变为“Beauty”类。043行,新增加了一个栈对象:jiaLing,也是Beauty。048行,对应增加了嘉玲的自我介绍。

请编译、运行该程序,观察“人”与“美人”的输出内容。

[回到目录]
白话C++

你可能感兴趣的:(第3章 感受(一)——3.9. Hello object 派生版)