public继承意味着“is-a”关系。它的意思是:如果B以public形式继承自A,那么B类型对象肯定是一个A对象,反之不成立。A是B的一种抽象,B是A的特例。任何使用A的地方,都能使用B。
但是,有时候会犯认识上的错误:比如为类bird定义了函数“fly”,但是当我们从bird派生出企鹅Penguin时,却发现企鹅应该是不会飞的。这该怎么办呢?
第二,我们可以为企鹅重新定义一个fly函数,然后让它产生错误:
它的基本思想是:企鹅会飞,但是这种尝试是错误的。
和第一种相比,这是运行时错误,只有当程序运行时才能检测出来;而第一种是编译时错误,p.fly()本身就不能被调用。
第三种做法,就是对penguin不定义fly函数,这样当你试图调用时也会出错。
总之,public继承意味着“is-a”,适用于调用基类的函数肯定能调用派生类。
但是,有时候会犯认识上的错误:比如为类bird定义了函数“fly”,但是当我们从bird派生出企鹅Penguin时,却发现企鹅应该是不会飞的。这该怎么办呢?
第一,我们可以修改我们的设计:
class Bird
{
};
class CanFly:public Bird
{
public:
virtual void fly() ;
};
class CannotFly:public Bird
{
};
class Penguin:public CannotFly
{
};
第二,我们可以为企鹅重新定义一个fly函数,然后让它产生错误:
class Bird
{
public:
virtual void fly(){}
};
class Penguin
{
public:
void fly()
{
throw runtime_error("attempt to make a penguin fly");
}
};
在调用函数中:
Penguin p;
try{
p.fly();
}
catch(const runtime_error &e)
{
cerr<<e.what()<<endl;
}
它的基本思想是:企鹅会飞,但是这种尝试是错误的。
和第一种相比,这是运行时错误,只有当程序运行时才能检测出来;而第一种是编译时错误,p.fly()本身就不能被调用。
第三种做法,就是对penguin不定义fly函数,这样当你试图调用时也会出错。
总之,public继承意味着“is-a”,适用于调用基类的函数肯定能调用派生类。