当前位置:  开发笔记 > 编程语言 > 正文

基于原型与基于类的继承

如何解决《基于原型与基于类的继承》经验,为你挑选了3个好方法。

在JavaScript中,每个对象都是实例和类.要进行继承,可以使用任何对象实例作为原型.

在Python,C++等中,有类和实例作为单独的概念.为了进行继承,您必须使用基类来创建一个新类,然后可以使用它来生成派生实例.

为什么JavaScript会朝这个方向发展(基于原型的面向对象)?基于原型的OO相对于传统的,基于类的OO有哪些优点(和缺点)?



1> Charlie Mart..:

这里有大约一百个术语问题,主要是围绕某人(不是你)试图让他们的想法听起来像The Best.

所有面向对象的语言都需要能够处理几个概念:

    封装数据以及对数据的相关操作,不同地称为数据成员和成员函数,或者作为数据和方法等.

    继承,能够说这些对象就像其他一组对象一样,除了这些更改

    多态("多种形状"),其中一个对象自己决定要运行哪些方法,以便您可以依赖语言来正确地路由您的请求.

现在,就比较而言:

首先是整个"阶级"与"原型"问题.这个想法最初是在Simula中开始的,其中使用基于类的方法,每个类表示一组共享相同状态空间(读取"可能值")和相同操作的对象,从而形成等价类.如果你回顾一下Smalltalk,因为你可以打开一个类并添加方法,这实际上与你在Javascript中可以做的一样.

后来的OO语言希望能够使用静态类型检查,因此我们在编译时得到了固定类集的概念.在开放阶段版本中,您具有更大的灵活性; 在较新的版本中,您可以在编译器上检查某些类型的正确性,否则需要进行测试.

在"基于类"的语言中,复制发生在编译时.在原型语言中,操作存储在原型数据结构中,在运行时复制和修改.但是,抽象地说,类仍然是共享相同状态空间和方法的所有对象的等价类.当您向原型添加方法时,您将有效地创建新等价类的元素.

现在,为什么这样做?主要是因为它在运行时创建了一个简单,合理,优雅的机制.现在,要创建新对象创建新类,您只需执行深层复制,复制所有数据和原型数据结构.您可以或多或少地免费获得继承和多态性:方法查找总是包括通过名称向字典询问方法实现.

最终出现在Javascript/ECMA脚本中的原因基本上就是当我们10年前开始使用它时,我们处理的是功能较弱的计算机和不太复杂的浏览器.选择基于原型的方法意味着解释器可以非常简单,同时保留面向对象的理想属性.


**有用的答案**.+1评论中不太有用的垃圾.我的意思是CLOS或Smalltalk是第一个有所不同吗?无论如何,这里的大多数人都不是历史学家.
@Stephano,他们并不是那么明显:Python,Ruby,Smalltalk使用字典进行方法查找,javascript和Self有类.在某种程度上,您可能会认为差异只是面向原型的语言暴露了他们的实现.所以不要把它变成一笔大交易可能是好事:它可能更像是EMACS和vi之间的争论.
不,抱歉,CLOS来自80年代后期的http://dreamsongs.com/CLOS.html Smalltalk,来自1980年http://en.wikipedia.org/wiki/Smalltalk和Simula,完全面向对象,从1967-68 http:/ /en.wikipedia.org/wiki/Simula

2> Vijay Mathew..:

可以在文章中找到一种比较偏向于基于原型的方法的比较 - 自我:简单的力量.本文提出以下论据支持原型:

通过复制创建.从原型创建新对象是通过简单的操作,复制,用简单的生物学比喻,克隆来完成的.从类创建新对象是通过实例化完成的,其中包括对类中格式信息的解释.实例化类似于从计划中建造房屋.复制对我们的吸引力比实例化更简单.

预先存在的模块的示例.原型比类更具体,因为它们是对象的示例,而不是格式和初始化的描述.这些示例可以帮助用户通过使模块更易于理解来重用模块.基于原型的系统允许用户检查典型的代表,而不是要求他从其描述中理解.

支持独一无二的对象.Self提供了一个框架,可以轻松地包含具有自己行为的独一无二的对象.由于每个对象都有命名的插槽,并且插槽可以保存状态或行为,因此任何对象都可以具有唯一的插槽或行为.基于类的系统设计用于存在许多具有相同行为的对象的情况.没有语言支持对象拥有自己独特的行为,并且创建一个保证只有一个实例的类是很尴尬的(想想Singleton模式).自我也没有这些缺点.可以使用自己的行为自定义任何对象.唯一对象可以保存唯一行为,不需要单独的"实例".

消除meta回归.基于类的系统中的任何对象都不能自给自足; 需要另一个对象(它的类)来表达它的结构和行为.这导致概念上无限的元回归:a point是类 Point的实例Point,它是元类的实例,它是metametaclass的一个实例 Point,ad infinitum.另一方面,在基于原型的系统中,对象可以包括其自身的行为; 没有其他目标需要为其注入生命.原型消除了元回归.

Self可能是实现原型的第一种语言.(它还开创了其他有趣的技术,如JIT,后来进入JVM.所以阅读其他自学论文也应该是有益的).


RE:消除元回归:在基于类的Common Lisp对象系统中,`point`是类`Point`的实例,它是元类`standard-class`的实例,它是一个实例本身,ad finitum.

3> Amit..:

你应该看看Douglas Crockford写的一本关于JavaScript的好书.它为JavaScript创建者所做的一些设计决策提供了很好的解释.

JavaScript的一个重要设计方面是其原型继承系统.对象是JavaScript中的一等公民,以及常规函数也被实现为对象('Function'对象是精确的).在我看来,当它最初设计为在浏览器中运行时,它意味着用于创建大量的单例对象.在浏览器DOM中,您可以找到窗口,文档等所有单例对象.此外,JavaScript是松散类型的动态语言(与强类型的动态语言Python相反),因此,通过使用'prototype'属性实现了对象扩展的概念.

所以我认为在JavaScript中实现了基于原型的OO的一些优点:

    适用于松散类型的环境,无需定义显式类型.

    使单例模式变得非常容易(在这方面比较JavaScript和Java,你会知道我在说什么).

    提供在不同对象的上下文中应用对象的方法,从对象等动态添加和替换方法的方法(在强类型语言中不可能的事情).

以下是原型OO的一些缺点:

    没有简单的方法来实现私有变量.可以使用Crockford的魔法使用闭包来实现私有变量,但它绝对不像在Java或C#中使用私有变量那么简单.

    我不知道如何在JavaScript中实现多重继承(其价值).


Crockford已经做了很多工作来破坏JavaScript,因为一种相当简单的脚本语言已经变成了对其内部的强制性迷恋.JS没有真正的私有关键字范围或真正的多重继承:不要试图伪造它们.
只需使用私有变量的命名约定,就像Python一样.
推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有