- 最重要的一点:在public继承的时候:Derived is-a Base ; Base not is-a Derived
- Derived和Base的关系
class Person {}; class Student :public Person {}; void eat(const Person& p); void study(const Student& s); int main() { Person p; Student s; eat(p); //对 p is p eat(s); //对 s is-a p study(s); //对 s is s study(p); //错 p not is-a s return 0; }
- Student 类可以理解Person类, Person类不能作为Student类。所以study(p)是不对的。
- 错误的继承理解带来错误的代码
- 比如鸟(bird)会飞,企鹅(Penguin)是一种鸟。于是有如下代码
class Bird { public: virtual void fly() { cout << "default fly" << endl; }; }; class Penguin :public Bird { virtual void fly() { // 方法1 cout << "Penguin can not fly" << endl; //方法2:空实现 //方法3:编译报错 error("Penguin can not fly"); }; };
但实际上企鹅并不会飞,所以企鹅中不该有fly函数,但若必须有,我个人比较推荐做法是空实现+LOG。但理论上最好的是编译过程中报错,不让错误待到程序运行阶段。
- 所以 对于public的继承有个结论:Derived类拥有Base类的所有属性和方法,所以设计可能不太象是第一直觉的继承关系。
- 总结:“public继承”意味着is-a。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象