is-a关系从字面上理解是一个从属派生关系,举个例子就是:“学生是人”,但这句话反过来则不成立,
void error(const std::string& msg);//报错函数定义于另外某处
class penguin:public Bird{
public:
virtual void fly()
{
error("attempt to make a penguin fly!")
}
......
};
在C++中,public继承必须满足is-a关系,如果子类B和父类A满足is-a关系,则A对象能够排上用场的地方,B对象一定可以用,父类表现的是一般化的形式,而子类表示的是特殊化的概念。
注意事项1:
好的接口可以防止无效的代码通过编译,例如:鸟都可以飞,企鹅是鸟,但是企鹅不会飞,这看似违反了is-a关系,其实,这个和语言表达方式有关,当我们说鸟会飞的时候,意思是表达一部分鸟会飞,而不是说所有的鸟都会飞,因此,再设计继承关系是就要注意这点,基类鸟中不应该含有飞函数,会飞的鸟和不会飞的鸟分别继承鸟类,在会飞的鸟中实现飞函数,在不会飞的类中不用实现飞函数。具体如下所示:
针对上述问题的另外一个解决方法是是企鹅类继承鸟类,并且实现飞函数,但是,函数体内会报错信息,这样当该函数被调用时就会报错,这是符合正常逻辑的。
class Bird{
...
};
class flyBird:public Bird{
virtual void fly(); //声明飞方法
};
class penguin:public Bird{ //不声明飞方法
};
summary:
public继承意味着is-a。适用于base classes身上的每一件事情一定适用于derived classes身上,因为每一个derived对象也都是base class对象。