动态语言中的继承vs mixins?


19

什么时候应该使用继承模式而不是动态语言中的mixins?

所谓混入,是指实际正确混入,例如在运行时将函数和数据成员插入对象中。

例如,什么时候使用原型继承而不是mixins?为了更清楚地说明我的意思,mixin,一些伪代码:

asCircle(obj) {
  obj.radius = 0
  obj.area = function() {
    return this.radius * this.radius * 3.14
  }

myObject = {}
asCircle(myObject)
myObject.area() // -> 0

2
Mixins更像跨领域而不是直接继承。那可能会为您定义一些用例。
ashes999 2011年

1
组成,任何人:)
OnesimusUnbound,2011年

Answers:


14

原型继承很简单。与mixin相比,它具有单一优势。

那是一个实时链接。如果更改原型,则继承它的所有内容都会更改。

使用pd的示例

var Circle = {
  constructor: function _constructor() {
    this.radius = 0;
    return this;
  },
  area: function _area() {
    return this.radius * this.radius * Circle.PI
  },
  PI: 3.14
};

var mixedIn = pd.extend({}, Circle).constructor();
var inherited = pd.make(Circle, {}).constructor();

Circle.perimeter = perimeter;

inherited.perimeter(); // wins
mixedIn.perimeter(); // fails

function perimeter() {
  return 2 * this.radius;
}

因此,基本上,如果您希望对“接口” Circle进行更改以在运行时反映“使用”其功能的所有对象,则可以从中继承。

如果您不希望更改反映出来,则将其混入。

请注意,mixins的用途也远不止于此。Mixins是您实现多重“继承”的机制。

如果您希望一个对象实现多个“接口”,则必须其中的一些进行混合。用于原型继承的一个是要在运行时反映出来的一个,其他将被混合。


12

我的马感告诉我:

  • 如果多个对象或类层次结构中有用的东西-将其混合
  • 如果事情是唯一有用沿着一个层次-使用继承

相关注意事项:

  • “有用”一词应该用隐喻来表示
  • 对于那些没有多重继承的语言,mixin是一个很好的选择
  • PHP 5.4引入了混合源和多重继承世界都具有优势的特征

+1是我最喜欢的Ruby中“对多个对象或类层次结构有用的东西”的示例是Enumerable模块:ruby-doc.org/core-1.9.3/Enumerable.html
David

1
我想说,多重继承可以替代mixins(不是很好)。
西蒙·贝格

@Simon我要说的是,mixins可以替代多重继承(不是很好);)
Raynos 2011年

我的马感也告诉了我。:)
theringostarrs

9

使用“ Is-a”测试。

继承仅限于您可以说“子类是超类”的情况。他们是同一种东西。“奶酪是乳制品”。

Mixins适用于其他所有功能。“奶酪可以用于三明治”。奶酪不是三明治,但它参与三明治。

PS。这与动态语言无关。具有静态编译功能(即C ++)的任何多继承语言都具有相同的决策点。


绝对+ 1-静态语言也具有mixin。
DeadMG

是的,mixin可以用多种语言完成-这不是我的问题。动态语言具有某些特性,这些特性可能会或可能不会使mixin变得不同和/或更有趣,Raynos指出了一个方面。此外,您没有指出为什么应该使用IS A概念而不是mixin概念的任何特定原因。
Magnus Wolffelt 2011年

@MagnusWolffelt:它们是同一种东西。“奶酪是乳制品”。这是IS-A的规则。我还要说什么?
S.Lott

我的问题更多是关于设计决策的问题-在什么情况下需要继承,以及出于什么原因?在动态语言中,除了Raynos所描述的之外,我几乎没有理由选择对mixin继承。对象创建的性能可能是原因之一。
Magnus Wolffelt,2011年

@MagnusWolffelt:“您希望在什么情况下继承”当两个类满足IS-A关系时。“对象创建的性能”不是选择一个对象的理由。继承对这两个对象类做出了非常有力的说明。Mixins给出了一个较弱且更灵活的声明。当两个类满足“ IS-A”关系时,将使用继承。我还能说什么?我不太了解你的问题。您能否阐明您想知道的更多信息?
S.Lott

0

好吧,我能提供给您的最好的例子是游戏演员,演员具有一些基本知识,但是使用了混合功能/ 插件来共享功能。共享功能可以是(直接从源代码!):

var plugins = {
    SingleVisualEntity : SingleVisualEntity,
    JumpBehaviour      : JumpBehaviour,
    WeaponBehaviour    : WeaponBehaviour,
    RadarBehaviour     : RadarBehaviour,
    EnergyGatherer     : EnergyGatherer,
    LifeBarPlugin      : LifeBarPlugin,
    SelectionPlugin    : SelectionPlugin,
    UpgradePlugin      : UpgradePlugin,
    BrainPlugin        : BrainPlugin,
    PlanetObjectPlugin : PlanetObjectPlugin,
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.