public继承经过仔细的检查后发现主要有两部分组成:函数接口继承和函数实现继承,他们的区别就相当于声明与定义的区别。作为类的设计者你有可能希望继承接口,有可能继承实现或者两者都需要。、
class Sharp
{
public:
virtual void draw() cosnt = 0;
virtual void error(const std::string& msg);
int objectId() const;
......
};
class Rect:public Sharp{......};
class Ellipse:public Sharp{......};
这里Sharp是个抽象类,他的成员函数的接口总会被继承,因为这是public继承
首先看纯虚函数,他们需要被继承了他的具象重新声明,而且在抽象类中通常是没有定义的。所以一般来说,纯虚函数的目的是为了让派生类只继承函数接口。意外的是我们可以为纯虚函数提供定义。但是调用它需要指明类名。
非纯虚函数和纯虚函数有点不一样。一如既往,他会继承其接口,但是他会提供一份代码派生类可能覆写他。所以提供impure virtual是为了让派生类继承其接口和缺省实现。类Sharp中的error就是如此。但是提供缺省是可能造成危险的。
class Airport{.......};
class Airplane
{
public:
virtual void fly(const Airport& dest);
.....
};
void Airplane::fly(const Airport& dest)
{
.........
}
class ModelA:public Airplane{.......};
class ModelB:public Airplane{.........};
A和B写了相同的代码,他们使用了缺省的行为。
现在我们需要代码扩展:
class ModelC:public Airplane{
........
};
我们的需求是C和A、B的行为是不一样的。如果我们直接使用就会造成使用缺省行为而导致错误。改进的办法是:
class Airplane{
public:
virtual void fly(const Ariport& dest) = 0;
.......
protected:
void defaultFly(const Airport& dest);
};
void Airplane::defaultFly(const Airport& dest)
{
缺省行为
}
class ModelA:public Airplane
{
public:
virtual void fly(const Airport& dest)
{ defaultFly(dest); }
} ;
class ModelB:public Airplane
{
public:
virtual void fly(const Airport& dest)
{ defaultFly(dest); }
} ;
class ModelC:public Airplane{
public:
virtual void fly(const Airport& dest)
{
指定C的目的地
}
........
};
这个方案比之前那个好,但是还有可能错误,比如你习惯了剪切之类的
另外的方法;
class Airplane
{
public:
virtual void fly(const Airport& dest) =0;
....
};
void Airplane::fly(const Airport& dest)
{
缺省行为
}
class ModelA:public Airplane
{
public:
virtual void fly(const Airport& dest)
{ Airplane::fly(dest); }
....
};
class ModelB:public Airplane
{
public:
virtual void fly(const Airport& dest)
{ Airplane::fly(dest); }
....
};
class ModelC:public Airplane
{
public:
virtual void fly(const Airport& dest);
....
};
void ModelC::fly(const Airport& dest)
{
将C飞机飞到指定的目标
}
这个设计中使用了pure virtual函数Airplane::fly()替换了独立函数Airplane::defaultFly。本质上现在fly分成了两个基本要其声明部分表现的接口(那就是派生类必须用的),其定义部分表现为缺省行为(派生类可能使用的)最后我们来看Sharp的objectId函数,这表明public继承体系派生类的强制实现。
说了这么多,我们很清楚了,应该根据不同的需求声明为不同的函数。