通过类和方法的多态性是不是很糟糕? (2)

时间:2010-03-02 17:44:36

标签: polymorphism

我最近读过,通过类和方法的多态性是一种关于多态性的坏方法。为什么这是一个问题,有哪些替代方案?

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

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

5 个答案:

答案 0 :(得分:4)

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

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

class Animal;
class Mammal : public Animal;
class Dog : public Mammal;
class Cat : public Mammal;
class Fish : public Animal;

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

class Animal;
class SwimmingAnimal: public Animal;
class Dog : public SwimmingAnimal;
class Fish: public SwimmingAnimal;
class NonSwimmingAnimal: public Animal;
class Cat : public NonSwimmingAnimal;

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

使用接口可以解决许多这些问题,但需要付出代价。

class Animal;
class Dog : public Animal, public IMammal, public SwimmingAnimal;
class Cat : public Animal, public IMammal;
class Fish: public Animal, public SwimmingAnimal;

由于类只从接口继承,因此无法轻松共享相同的功能。因此,必须通过遏制来实现共享功能。如果Dog和Fish想要提供'游泳'功能,他们必须提供游泳方法,并通过将其调用转发到单独的Swim类来实现它,类似这样(这是所有伪代码):

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

答案 1 :(得分:3)

我个人并不认为通过类的多态性是“坏” - 但是,还有其他选择......

我觉得真正的问题是认为多态是编写软件的唯一方法是不好的。我们可以从使用函数式编程技术中学到许多经验教训,例如,它可以解决传统OOP实践中的许多限制,例如在大量并发环境中缓解线程安全性(这似乎是关联点之一)。

很多时候,问题会比多态性更优雅 - 通常,将多态性与功能概念混合可以产生非常优雅的解决方案。

答案 2 :(得分:3)

编程中确实没有银弹。在所有情况下说XY更好是完全错误的。在编写软件时,我倾向于遵循以下准则。

  1. 当我有一个定义良好的对象模型时使用继承。
  2. 在不相关的对象之间共享功能时使用合成。
  3. 利用功能技术填补空白,提升线程安全性。

答案 3 :(得分:2)

取决于。

目前的趋势是赞成合成而不是继承。并行编程也提升了对功能范例的兴趣。

但继承,多态和面向对象本质上并不“坏”,也不会很快消失。

尽可能多地学习技巧。了解何时应用它们以及权衡取舍(因为总是存在权衡)。适当使用它们。

答案 4 :(得分:1)

您提供的链接没有说“通过类和方法的多态性是坏的” 它只是说 “你可以通过避免所谓的”最佳实践“来对抗Dyads 我不知道他在说谁