原书抄录:
- 在软件开发中, 抽象处于中心地位,而类则是C++中最重要的抽象机制。类描述的是所有有这个类实例的对象的共同属性,并且刻画了这些实例化的对象的共同行为。
- 优良设计的设计代码总是比拙劣设计的代码更短, 这是因为在好的设计中通常都使用了正确的抽象。
- 如果在所有的对象中都存在这共同的抽象时,那么继承层次越简单,形成的模型越精确。
规则总结:
● 将共同的抽象提取出来并放到基类中
● 一个类应给能够描述一组对象
● 如果派生类之间的区别在于属性, 则用数据成员来表示;如果在于行为, 则用于虚函数来表示
● 如果通过公共继承来继承来产生派生类, 那么这个派生类应该是基类的特化
● 多态并不是所有程序设计问题的解决方案
章后练习题
原题如下:
分析程序清单 1-4中的类。函数main()输出的结果如下所示:
The atomic weight:196.9665
The atomic number:79
Price per ounce:450.75
应用本章中所学到的规则, 对程序中的抽象及相应的类进行评价。(标识符Pb和Au是化学符号, 分别表示铅和金, 这两个名字来自拉丁文plumbum和aurum。)
程序清单 1-4 类Pb 和 类Au
(注:#include <iostream.h>
改成了#include <iostream>
)
#include <iostream>
using namespace std;
class Pb
{
private:
unsigned atomicNumber;
float atomicWeight;
float pricePerOunce;
public:
Pb(void)
{
atomicNumber = 82;
atomicWeight = 207.2;
pricePerOunce = 0.01;
}
unsigned getNumber(void) { return atomicNumber; }
float getWeight(void) { return atomicWeight; }
float getPrice(void) { return pricePerOunce; }
void output(void)
{
cout << "The atomic weight: " << atomicWeight << "\n";
cout << "The atomic number: " << atomicNumber << "\n";
cout << "Price per ounce: " << pricePerOunce << "\n\n";
}
};
class Au
{
private:
unsigned atomicNumber;
float atomicWeight;
float pricePerOunce;
public:
Au(void)
{
atomicNumber = 79;
atomicWeight = 196.9665;
pricePerOunce = 450.75;
}
Au(Pb& lead)
{
atomicWeight = lead.getWeight() - 10.2335;
atomicNumber = lead.getNumber() - 3;
pricePerOunce = 450.75;
}
void output(void)
{
cout << "The atomic weight: " << atomicWeight << "\n";
cout << "The atomic number: " << atomicNumber << "\n";
cout << "Price per ounce: " << pricePerOunce << "\n\n";
}
};
main()
{
Pb myLead;
Au myGold = myLead;
myGold.output();
}
根据第一条规则, 两个类很明显存在一些共同的抽象:
数据成员:
unsigned atomicNumber;
float atomicWeight;
float pricePerOunce;
和成员函数:
void output(void);
因此我可以写一个基类, 抽象出这些成员:
class automic
{
private:
unsigned atomicNumber;
float atomicWeight;
float pricePerOunce;
public:
void output(void);
};
而第二条规则, 在这个代码中根本没有体现到, 这里的类Ab和Au都只能针对于特定的元素。
其它的规则也没用体现到。
根据规则(也没有完全弄明白, 待日后再慢慢消化)改进的代码:
#include <iostream>
using namespace std;
class atomic
{
private:
unsigned atomicNumber;
float atomicWeight;
float pricePerOunce;
public:
atomic(unsigned am, float aw, float ppo)
{
atomicNumber = am;
atomicWeight = aw;
pricePerOunce = ppo;
}
unsigned getNumber(void) { return atomicNumber; }
float getWeight(void) { return atomicWeight; }
float getPrice(void) { return pricePerOunce; }
void output(void)
{
cout << "The atomic weight: " << atomicWeight << "\n";
cout << "The atomic number: " << atomicNumber << "\n";
cout << "Price per ounce: " << pricePerOunce << "\n\n";
}
};
class Pb: public atomic
{
public:
Pb(void):
atomic(82, 207.2, 0.01)
{}
};
class Au: public atomic
{
public:
Au(void):
atomic(79, 196.9665, 450.75)
{}
Au(Pb& lead):
atomic(lead.getWeight() - 10.2335, lead.getNumber() - 3, 450.75)
{}
};
main()
{
Pb myLead;
Au myGold = myLead;
myGold.output();
}
首先抽象出一个基类, 用于保存公共的的成员。
类Pb和Au的数据成员的区别在于具体的值, 而我们根据atomic基类可以构造出任意的具体元素类, 因此Pb和Au类是atomic基类的特化版本使用public继承。
这里Au类可以根据Pb对象构造出来, 因此是Au的特有行为。
初学C++, 文中有错误纰漏之处见谅, 请C++大虾多多指教。