Java是100%面向对象的吗?
Java具有不像Ruby中那样从对象派生的原始数据types。 那么我们可以认为Java是一种100%面向对象的语言吗? 另一个问题:Java为什么不devise原始数据types的对象方式?
当Java第一次出现(版本1.x)时,JVM真的很慢。 不把原语作为一stream的对象来实现,这是他们为了速度的目的而采取的妥协scheme,尽pipe从长远来看,这是一个非常糟糕的决定。
“面向对象”对很多人来说也意味着很多东西。 你可以有基于类的OO(C ++,Java,C#),或者你可以有基于原型的OO(Javascript,Lua)。
100%面向对象并不意味着太多,真的。 Ruby也有不时遇到的问题。
关于Java的困扰是,它不能提供有效抽象思想的手段,扩展有问题的语言。 每当这个问题被提出(见盖伊·斯蒂尔的“成长一种语言”),“哦,不,但乔·斯派克呢? 论点是给出的。 即使你devise的语言可以防止自己在脚下的射击,但意外的复杂性和真正的复杂性之间还是有区别的(见No Silver Bullet ),平庸的开发者总是会find创造性的方法来自我射击。
例如,Perl 5不是面向对象的,但它足够可扩展,它允许Moose这个对象系统,它允许非常先进的技术来处理面向对象的复杂性。 而语法糖是没有问题的。
不,因为它的数据types不是对象(如int
和byte
)。 我相信Smalltalk是真正的面向对象的,但是我对这个语言只有一点点经验(五年前大约两个月)。
我也听到了Ruby人群的声明,但是我对这种语言没有任何经验。
当然,这是使用“真正的OO”的定义,这意味着它只有对象,没有其他types。 其他人可能不同意这个定义。
看来,经过对Python的一些研究(我不知道名称/对象的区别,尽pipe编了一年左右 – 更愚弄我,我想),它可能确实是真正的面向对象。
下面的代码工作正常:
#!/usr/bin/python i = 7 print id(i) print type(i) print i.__str__()
输出:
6701648 <type 'int'> 7
所以即使基本整数是对象在这里。
为了达到真正的100%OO认为Smalltalk,例如, 一切都是一个对象,包括编译器本身,甚至if
语句: ifTrue:
是一个带有一个代码参数块的布尔值的消息。
Java不是100%的OO。 Java可能会走向99%OO(想想自动装箱,Scala)。 我会说Java现在是87%的OO。
为什么java不以对象的方式devise原始数据types?
早在90年代就有性能方面的原因,同时Java保持向后兼容。 所以他们不能把它们拿出来。
问题是面向对象的定义不是很好,可能意味着很多东西。 这篇文章更详细地解释了这个问题: http : //www.paulgraham.com/reesoo.html
此外,Alan Kay(Smalltalk的发明者和“面向对象”这个术语的作者(?))着名地说过,当考虑到OOP时,他并没有考虑C ++。 所以我认为这也适用于Java。
语言完全是面向对象(无论是什么意思)是可取的,因为它意味着更好的正交性,这是一件好事。 但是鉴于Java在其他方面并不是非常正交的,它的OO不完整性在实践中可能并不重要。
不,Java不是,因为它有原始的数据types,与对象不同(它们没有方法,实例variables等)。 而Ruby则完全是OOP。 一切都是一个对象。 我可以做这个:
1.class
它将返回1(Fixnum,这基本上是一个数字)的类。 你不能用Java来做到这一点。
爪哇,因为你提到的原因,并没有使它成为一个纯粹的面向对象的编程语言。 然而,每个程序都是一个类的执行使得它非常面向面向对象编程。
Ruby,正如你所提到的,碰巧也是我脑中想到的第一个语言,是一种没有原始语言的语言,所有的价值都是客体。 这确实使它比Java更面向对象。 另一方面,据我所知,并不要求一段代码必须与一个类相关联,就像Java一样。
也就是说,Java确实有包装Integer
, Boolean
, Character
等基元的对象。 具有原语的原因可能是在Peter的回答中给出的原因 – 当Java在90年代中期被引入时,系统上的内存大部分是两位数兆字节,因此每个值都是一个对象是一个大的开销。
(大,当然是相对的,我不记得确切的数字,但是一个对象的开销大约是50到100个字节的内存,绝对大于原始值所需的几个字节的最小值)
今天,许多具有多吉字节内存的桌面,对象的开销不成问题。
“为什么java不把对象的方式devise成原始数据types?”
在Sun开发者日子里,几年前我记得James Gosling回答了这个问题。 他说,他们喜欢完全从原始的东西中抽象出来 – 只留下标准的东西,但后来用完了,决定用原来的东西来运送。 很伤心。
那么我们可以认为java是100%面向对象的语言吗?
没有。
另一个问题:为什么java不把对象的方式devise成原始数据types?
主要是出于性能方面的原因,也可能对来自C ++的人更加熟悉。
Java不能清除非对象原语( int
等)的一个原因是它不支持原生数据成员。 想像:
class int extends object { // need some data member here. but what type? public native int(); public native int plus(int x); // several more non-mutating methods };
第二个想法,我们知道Java维护每个对象的内部数据(锁等)。 也许我们可以定义没有数据成员的class int
,但是使用操作这个内部数据的本地方法。
剩余的问题:常量 – 但这些可以类似地处理string。 虽然我们需要小心int.plus(float)
返回float
, float.plus(int)
等等,但是操作符只是语法上的糖和+
并且会在编译时执行plus
方法。
最终,我认为原语的理由是效率:静态分析需要确定一个int
对象可以被纯粹当作JVM整数值,当devise语言时可能被认为是一个太大的问题。
我会说完整的OO语言是那些有他们的元素(类,方法)作为对象可以访问的对象。
从这个POV来看,Java并不是完全的OOP语言,JavaScript是(不pipe它有什么原始的)。
根据程序devise语言学的概念 ,有一个叫做Ingalls的testing,由Ingresss的Smalltalk小组的领导者Dan Ingalls提出。 那是:
你可以定义一种新的整数,把你的新整数放入矩形(已经是窗口系统的一部分),请求系统把一个矩形变黑,并使一切正常工作?
而且根据Smalltalk的书通过这个testing,但是C ++和Java没有。 不幸的是,书不能在线提供,但这里有一些支持幻灯片 (幻灯片33回答你的问题)。
没有,例如,Javascript是。
那些Integer,Long和Boolean类会被写入? 你将如何编写一个没有原始数组的ArrayList或HashMap?
这是在学术界真正重要的问题之一。 Ruby被优化以尽可能地将int,long等等视为原语。 Java只是明确表示了这一点。 如果Java有原语是对象,那么会有IntPrimitive,LongPrimitive等(不pipe名字)类。 如果没有特殊的方法,这很可能是最终的(例如没有IntPrimitive.factorial)。 这对于大多数目的来说意味着它们将是原始的。
Java显然不是100%的OO。 您可以轻松地以程序风格对其进行编程。 大部分人都这么做 诚然,图书馆和容器往往不能宽恕这种范式。
Java不完全是面向对象的。 我会考虑Smalltalk和Eiffel最stream行的完全面向对象的语言。