Deriving an abstract class from concrete class

后端 未结 7 834
囚心锁ツ
囚心锁ツ 2021-02-05 16:05

Let\'s say we have a concrete class Apple. (Apple objects can be instantiated.) Now, someone comes and derives an abstract class Peach from Apple. It\'

7条回答
  •  暖寄归人
    2021-02-05 16:43

    Re Peach from Apple:

    • Don't do it if Apple is a value class (i.e. has copy ctor, non-identical instances can be equal, etc). See Meyers More Effective C++ Item 33 for why.
    • Don't do it if Apple has a public nonvirtual destructor, otherwise you invite undefined behaviour when your users delete an Apple through a pointer to Peach.
    • Otherwise, you're probably safe, because you haven't violated Liskov substitutability. A Peach IS-A Apple.
    • If you own the Apple code, prefer to factor out a common abstract base class (Fruit perhaps) and derive Apple and Peach from it.

    Re Tomato from Berry:

    • Same as above, plus:
    • Avoid, because it's unusual
    • If you must, document what derived classes of Tomato must do in order not to violate Liskov substitutability. The function you are overriding in Berry - let's call it Juice() - imposes certain requirements and makes certain promises. Derived classes' implementations of Juice() must require no more and promise no less. Then a DerivedTomato IS-A Berry and code which only knows about Berry is safe.

    Possibly, you will meet the last requirement by documenting that DerivedTomatoes must call Berry::Juice(). If so, consider using Template Method instead:

    class Tomato : public Berry
    {
    public:
        void Juice() 
        {
            PrepareJuice();
            Berry::Juice();
        }
        virtual void PrepareJuice() = 0;
    };
    

    Now there is an excellent chance that a Tomato IS-A Berry, contrary to botanical expectations. (The exception is if derived classes' implementations of PrepareJuice impose extra preconditions beyond those imposed by Berry::Juice).

提交回复
热议问题