经典的Vs原型继承

时间:2009-09-20 08:21:21

标签: javascript oop

在阅读了两者后,我只是好奇,编程社区如何使用它? 在什么情况下?

3 个答案:

答案 0 :(得分:23)

经典继承存在许多与原型继承不存在的问题,例如:

经典继承

紧耦合。继承是OO设计中最紧密的耦合。后裔课程对他们的祖先课程有着深入的了解。

不灵活的层次结构(也就是必要的重复)。单父层次结构很少能够描述所有可能的用例。最终,所有层次结构对于新用途都是“错误的” - 这是一个需要重复代码的问题。

多重继承很复杂。通常需要从多个父级继承。该过程非常复杂,其实现与单继承的过程不一致,这使得它更难以阅读和理解。

脆弱的架构。由于紧密耦合,通常很难用“错误”设计重构类,因为现有的许多功能取决于现有设计。

大猩猩/香蕉问题。通常,您不希望继承父级的某些部分。子类化允许您覆盖父级的属性,但它不允许您选择要继承的属性。

原型继承

要了解原型继承如何解决这些问题,您应该首先了解有两种不同类型的原型继承。 JavaScript支持:

。如果在实例上找不到属性,则会在实例的原型上搜索该属性。这使您可以在许多实例之间共享方法,为您提供免费的 flyweight模式

级联。向对象动态添加属性的功能使您可以将任何属性从一个对象自由复制到另一个对象,所有这些属性可以一起或有选择地复制。

您可以结合两种形式的原型继承来实现非常灵活的代码重用系统。实际上非常灵活,用原型实现经典继承是微不足道的。反之则不然。

原型继承允许您在古典语言中找到的大多数重要功能。在JavaScript中,闭包和工厂函数允许您实现私有状态,并且功能继承可以很容易地与原型结合,以便添加支持数据隐私的mixin。

原型继承的一些优点:

松耦合。实例永远不需要直接引用父类或原型。可以存储对对象原型的引用,但不建议,因为这会促进对象层次结构中的紧密耦合 - 这是经典继承的最大缺陷之一。

平面层次结构。使用原型OO使继承层次结构保持平坦是微不足道的 - 使用连接和委托,您可以拥有单个级别的对象委派和单个实例,而不会引用父类。

琐碎的多重继承。从多个祖先继承就像使用串联组合多个原型的属性以形成新对象或新对象的新委托一样简单。

灵活的架构。由于您可以选择性地继承原型OO,因此您不必担心“错误的设计”问题。新类可以从任何源对象组合继承任何属性组合。由于层次结构扁平化的容易性,一个地方的变化不一定会导致整个长链后代对象的涟漪。

没有更多的大猩猩。选择性继承消除了大猩猩香蕉问题。

我不知道经典继承优于原型继承的任何优势。如果有人知道,请赐教。

答案 1 :(得分:8)

基于原型的继承更灵活。任何现有对象都可以成为一个类,从中生成其他对象。这对于您的对象提供多组服务和/或在程序到达需要继承的点之前经历了大量状态转换非常方便。

此处提供了有关建模方法的广泛讨论:http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

答案 2 :(得分:4)

由于Javascript不支持“经典​​”继承,因为大多数人都不会理解(并且你没有给出你所读过的内容的任何引用),我会假设你的意思是继承处理如下: -

 function base() {
    var myVar;
    this.someBaseFunc = function() { }
 }


 function derived() {
    base.call(this);
    var someOtherVar;
    this.SomeOtherFunc = function() { }
 }

我的一般经验法则是:

  • 如果类很复杂且实例很少,则使用“经典”方法。这允许类仅公开公开应该公开的那些功能。
  • 如果Class很简单且实例很多,则使用原型方法。这限制了在创建实例时一次又一次地定义和存储对函数的引用的开销。