Java 100%面向对象吗?

Java具有原始数据类型,它不像Ruby中的对象派生。 那么我们可以将Java视为100%面向对象的语言吗? 另一个问题:为什么Java不设计原始数据类型的对象方式?

当Java首次出现时(版本1.x),JVM真的非常非常慢。 不将原语作为一等对象实现是他们为速度目的而采取的妥协,尽管我认为从长远来看这是一个非常糟糕的决定。

“面向对象”对许多人来说也意味着很多东西。 你可以拥有基于类的OO(C ++,Java,C#),或者你可以拥有基于原型的OO(Javascript,Lua)。

100%面向对象并不意味着太多,真的。 Ruby也会遇到你不时会遇到的问题。

让我困扰Java的是它没有提供有效抽象思想的方法,而是将语言扩展到有问题的地方。 每当提出这个问题时(见Guy Steele的“成长语言”),“哦,不,但Joe Sixpack怎么样?” 给出了论证。 即使你设计的语言可以防止自己在脚下射击,但是偶然的复杂性和真正的复杂性之间存在差异(参见No Silver Bullet ),而平庸的开发人员总是会找到创造性的方式来拍摄自己。

例如,Perl 5不是面向对象的,但它足够可扩展,它允许Moose ,一个允许非常先进的技术来处理OO复杂性的对象系统。 语法糖也没问题。

要实现真正的100%OO认为Smalltalk,例如, 一切都是对象,包括编译器本身,甚至if语句: ifTrue:是一个带有代码块参数的布尔消息。

问题是面向对象的定义并不是很明确,可能意味着很多事情。 本文将更详细地解释该问题: http : //www.paulgraham.com/reesoo.html

此外,Alan Kay(Smalltalk的发明者和“面向对象”这一术语的作者(?))有一句名言说他在考虑OOP时没有考虑过C ++。 所以我认为这也适用于Java。

语言完全是OO(无论这意味着什么)是可取的,因为它意味着更好的正交性,这是一件好事。 但鉴于Java在其他方面无论如何都不是非常正交,其OO不完整性的一小部分在实践中可能无关紧要。

Java不是100%OO。 Java可能会达到99%的OO(想想自动装箱,Scala)。 我想说Java现在是87%的OO。

为什么java不将原始数据类型设计为对象方式?

早在90年代就有性能原因,同时Java保持向后兼容。 所以他们不能把它们拿出来。

不,Java不是,因为它具有原始数据类型,它们与对象不同(它们没有方法,实例变量等)。 另一方面,Ruby完全是OOP。 一切都是对象。 我可以做这个:

 1.class 

它将返回1的类(Fixnum,基本上是一个数字)。 你不能用Java做到这一点。

出于你提到的原因,Java具有原语,并不能使它成为纯粹的面向对象的编程语言。 然而,让每个程序成为一个类的强制执行使它非常面向面向对象的编程。

正如你所提到的,Ruby也恰好是我脑海中的第一种语言,它是一种没有原语的语言,所有的值都是对象。 这肯定会使它比Java更加面向对象。 另一方面,据我所知,没有要求一段代码必须与一个类相关联,就像Java一样。

也就是说,Java确实有包围原语的对象,如IntegerBooleanCharacter等。 原型的原因可能是彼得的答案中给出的原因 – 当Java在90年代中期引入时,系统上的内存大多数是两位数兆字节,因此将每个值都作为对象是一个很大的开销。

(大,当然是相对的。我不记得确切的数字,但是对象开销大约是50-100字节的内存。绝对超过原始值所需的几个字节的最小值)

今天,由于许多台式机具有多千兆字节的内存,因此对象的开销不再是问题。

“为什么java不将原始数据类型设计为对象方式?”

在Sun开发者时代,几年前我记得James Gosling回答这个问题。 他说,他们希望完全从原始人身上抽象出来 – 只留下标准物品,但是时间不多了,决定随身携带它们。 很伤心。

那么我们可以将java视为100%面向对象的语言吗?

没有。

另一个问题:为什么java不将原始数据类型设计为对象方式?

主要是出于性能原因,也可能对来自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 ,但使用操作此内部数据的本机方法。

剩余问题:常量 – 但这些可以与字符串类似地处理。 运算符只是语法糖和+并且会在编译时映射到plus方法,尽管我们需要注意int.plus(float)float.plus(int)一样返回float ,依此类推。

最后,我认为原语的合理性是效率:确定int对象可以纯粹作为JVM整数值处理所需的静态分析在设计语言时可能被认为是一个太大的问题。

我会说完全OO语言是那些可以作为对象使用它们的元素(类,方法)的语言。

从这个POV来看,Java并不是完全的OOP语言,而JavaScript则是(无论它有原语)。

根据“ 编程语言中的概念”一书 ,有一种名为Ingalls的测试,由Smalltalk小组的负责人Dan Ingalls提出。 那是:

你能定义一种新的整数,将你的新整数放入矩形(已经是窗口系统的一部分),要求系统将矩形变黑,并让一切都有效吗?

再次根据Smalltalk的书通过了这个测试,但C ++和Java没有。 不幸的是,书籍不在网上,但这里有一些支持幻灯片 (幻灯片33回答你的问题)。

不,例如,Javascript是。

那些Integer,Long和Boolean类会被写入什么? 如何在没有原始数组的情况下编写ArrayList或HashMap?

这是真正唯一在学术意义上重要的问题之一。 Ruby被优化为尽可能将int,long等作为原语处理。 Java只是明确了这一点。 如果Java将原语作为对象,则会有IntPrimitive,LongPrimitive等(通过任何名称)类。 如果没有特殊方法,最有可能是最终的(例如没有IntPrimitive.factorial)。 对于大多数目的而言,这意味着它们将是原始的。

Java显然不是100%OO。 您可以轻松地以程序样式对其进行编程。 大多数人这样做。 确实,图书馆和容器往往不能容忍这种范式。

Java不是完全面向对象的。 我会认为Smalltalk和Eiffel是最受欢迎的完全面向对象的语言。