通过类和方法实现的多态性不好吗?(2)

Joh*_*ker 2 polymorphism

我最近读到,通过类和方法实现多态性是实现多态性的糟糕方法。为什么这是一个问题?有哪些替代方案?

我知道这是一个有点主观的问题,但它是从函数式编程角度产生的一个合法问题,例如: http: //blog.thinkrelevance.com/2009/7/8/triadic-programming

如果你是一个靠类的多态性生活的程序员,我并不是在攻击你。我只是想了解对方。如果您有这种感觉,请随意解释为什么通过类进行多态性比某些替代方案更好。

Pat*_*ick 5

如果层次结构变得太大,多态性(或继承)可能会导致问题。

例如,拥有以下类可能是合乎逻辑的:

class Animal;
class Mammal : public Animal;
class Dog : public Mammal;
class Cat : public Mammal;
class Fish : public Animal;
Run Code Online (Sandbox Code Playgroud)

但如果在某个时刻你需要区分会游泳的动物(狗、鱼)和不会游泳的动物(想象一下猫不会游泳)。那么这样写会更合乎逻辑:

class Animal;
class SwimmingAnimal: public Animal;
class Dog : public SwimmingAnimal;
class Fish: public SwimmingAnimal;
class NonSwimmingAnimal: public Animal;
class Cat : public NonSwimmingAnimal;
Run Code Online (Sandbox Code Playgroud)

您可以尝试使用虚拟继承来实现这两个层次结构,但这很快会导致很多问题(其中之一也称为“钻石问题”)。

使用接口可以解决许多此类问题,但需要付出一定的代价。

class Animal;
class Dog : public Animal, public IMammal, public SwimmingAnimal;
class Cat : public Animal, public IMammal;
class Fish: public Animal, public SwimmingAnimal;
Run Code Online (Sandbox Code Playgroud)

由于类仅继承自接口,因此它们不能轻松地共享相同的功能。因此共享功能必须通过遏制来实现。如果 Dog 和 Fish 想要提供“游泳”功能,它们必须提供 Swim 方法,并通过将其调用转发到单独的 Swim 类来实现它,如下所示(这都是伪代码):

class Dog : public Animal, public IMammal, public SwimmingAnimal
{
public:
   void swim(double speed) {m_swim->swim(speed);}
private:
   Swim m_swim;
}
Run Code Online (Sandbox Code Playgroud)