条款34:区分接口继承与实现继承

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继承体系派生类的强制实现。

说了这么多,我们很清楚了,应该根据不同的需求声明为不同的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值