如果你编写类D(“派生类”)public继承类B(“基类”),就是在告诉C++编译器(以及代码的读者)每个类型D的对象都是类型B的对象,但反之则不然。
class Person {...};
class Student: public Person {...};
void eat(const Person& p); // 素有的Person都可以吃东西
void study(const Student& s); // 只有Student才可以上课学习
Person p; // p 是一个 Person对象
Student s; // s 是一个 Student对象
eat(p); // 没问题, p 是一个 Person对象
eat(s); // 没问题, s 是一个 Student对象,而一个Student必然是一个Person
study(s); // 没问题
study(p); // 错误! p不是一个Student对象
public继承和is-a的等价关系听起来很简单,但有时你的直觉可能会误导你。
class Bird {
public:
virtual void fly(); // 鸟会飞
...
};
class Penguin :public Bird { // 企鹅是鸟
...
};
下面的层次结构,它能更好地模拟实际的情况:
class Bird {
... // 没有定义飞的接口
};
class FlyingBird : public Bird {
public:
virtual void fly();
...
};
类Square应该public继承类Rectangle吗?
class Rectangle {
public:
virtual void setHeight(int newHeight);
virtual void setWidth(int newWidth);
virtual int height() const; // 返回当前值
virtual int width() const;
...
};
void makeBigger(Rectangle& r) // 增大r面积的函数
{
int oldHeight = r.height();
r.setWidth(r.width() + 10); // r的宽度加10
assert(r.height() == oldHeight); // 断言r的高度不变
}
class Square : public Rectangle { ... };
Square s;
...
assert(s.width() == s.height()); // 这对所有的正方形都成立
makeBigger(s); // 通过继承关系, s is-a Rectangle,
// 所以我们可以增加它的宽度
assert(s.width() == s.height()); // 这对所有正方形来说,这必须依然成立
public继承意味着“is-a”。适用于基类的所有内容也必须适用于派生类,因为每个派生类对象都是基类对象。