Java具有原始数据类型,它不是像Ruby中的对象派生的那样。那么我们可以将Java视为100%面向对象的语言吗?另一个问题:为什么Java没有设计原始数据类型的对象方式?
答案 0 :(得分:29)
当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复杂性的对象系统。 syntactic sugar没问题。
答案 1 :(得分:19)
不,因为它的数据类型不是对象(例如int
和byte
)。我相信Smalltalk是真正面向对象的,但我对这种语言只有一点经验(约五年前大约两个月)。
我也听过Ruby人群的说法,但我对这种语言有零的经验。
当然,这是使用“真正的OO”的定义,这意味着它只有对象而没有其他类型。其他人可能不同意这个定义。
看来,在对Python进行了一些研究之后(我不知道名称/对象的区别,尽管已经编写了一年左右的时间 - 我猜的更加愚弄我),它确实可能真的是OO。
以下代码可以正常使用:
#!/usr/bin/python
i = 7
print id(i)
print type(i)
print i.__str__()
输出:
6701648
<type 'int'>
7
所以即使基本整数也是这里的对象。
答案 2 :(得分:14)
要实现真正的100%OO认为Smalltalk,例如所有是一个对象,包括编译器本身,甚至是if
语句:ifTrue:
是一条消息发送到带有代码块参数的布尔值。
答案 3 :(得分:6)
问题是面向对象的定义并不是很明确,可能意味着很多事情。本文更详细地解释了该问题: http://www.paulgraham.com/reesoo.html
此外,Alan Kay(Smalltalk的发明者和“面向对象”这一术语的作者(?))着名地说,在考虑OOP时他没有考虑过C ++。所以我认为这也适用于Java。
语言完全是OO(无论这意味着什么)是可取的,因为它意味着更好的正交性,这是一件好事。但鉴于Java在其他方面无论如何都不是非常正交,其OO不完整性的一小部分在实践中可能无关紧要。
答案 4 :(得分:5)
Java不是100%OO。 Java可能会达到99%的OO(想想自动装箱,Scala)。 我会说Java现在是87%OO。
为什么java不设计原始数据 类型作为对象方式?
回到90年代,出现了性能原因,同时Java保持向后兼容。所以他们不能把它们拿走。
答案 5 :(得分:5)
不,Java不是,因为它有原始数据类型,它们与对象不同(它们没有方法,实例变量等)。另一方面,Ruby完全是OOP。 Everything 是一个对象。我可以这样做:
1.class
它将返回1的类(Fixnum,基本上是一个数字)。你不能用Java做到这一点。
答案 6 :(得分:3)
Java,出于你提到的原因,有原语,并不能使它成为一种纯粹的面向对象的编程语言。但是,让每个程序成为一个类的强制执行使它非常适合面向对象的编程。
Ruby,正如你所提到的,碰巧是第一种出现在我脑海中的语言,是一种没有原语的语言,所有的值都是对象。这确实使它比Java更加面向对象。另一方面,据我所知,没有要求一段代码必须与一个类相关联,就像Java一样。
也就是说,Java确实有包围诸如Integer
,Boolean
,Character
等原语的对象。原型的原因可能就是彼得的答案中给出的理由 - 当Java在90年代中期被引入时,系统上的内存大多数是两位数兆字节,所以将每个值都作为对象是一个很大的开销。
(大,当然是相对的。我不记得确切的数字,但是对象开销大约是50-100字节的内存。绝对超过原始值所需的几个字节的最小值)
今天,由于许多台式机具有多千兆字节的内存,因此对象的开销不再是问题。
答案 7 :(得分:2)
“为什么java不将原始数据类型设计为对象方式?”
在Sun开发者日,几年前我记得James Gosling回答这个问题。他说,他们希望完全从原始人身上抽象出来 - 只留下标准物品,但随后时间不多了,决定随身携带。很伤心。
答案 8 :(得分:1)
因此我们可以将java视为100%对象 导向语言?
没有
另一个问题:为什么java没有 将原始数据类型设计为对象 方式是什么?
主要是出于性能原因,也可能对来自C ++的人更熟悉。
答案 9 :(得分:1)
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
和{{1}等等。
最终我认为原语的合理性是效率:确定float.plus(int)
对象可以纯粹作为JVM整数值处理所需的静态分析可能在设计语言时被认为是一个太大的问题。 / p>
答案 10 :(得分:1)
我会说完整的OO语言是那些可以作为对象使用的元素(类,方法)的语言。
从这个POV,Java不是完全OOP语言,而JavaScript是(无论它有原语)。
答案 11 :(得分:1)
根据Concepts in Programming Languages book,有一种称为Ingalls测试的东西,由Dan Ingalls由Smalltalk小组的领导者提出。那就是:
你能定义一种新的整数吗? 把你的新整数放入矩形 (已经是窗口的一部分 系统),要求系统变黑a 矩形,一切正常吗?
再次根据Smalltalk的书通过了这个测试,但C ++和Java没有。不幸的是,这本书不在网上提供,但这里有一些支持slides(幻灯片33回答你的问题)。
答案 12 :(得分:0)
没有。例如,Javascript就是。
那些Integer,Long和Boolean类会被写入什么? 如何在没有原始数组的情况下编写ArrayList或HashMap?
答案 13 :(得分:0)
这是其中一个在学术意义上真正重要的问题。 Ruby被优化为尽可能将int,long等作为原语处理。 Java只是明确了这一点。如果Java将原语作为对象,则会有IntPrimitive,LongPrimitive等(通过任何名称)类。如果没有特殊方法(例如没有IntPrimitive.factorial),这很可能是最终的。对于大多数目的而言,这意味着它们将是原始的。
答案 14 :(得分:0)
Java显然不是100%OO。您可以轻松地以程序样式对其进行编程。大多数人这样做。的确,图书馆和容器往往不会容忍这种范式。
答案 15 :(得分:-1)
Java并非完全面向对象。我会认为Smalltalk和Eiffel是最受欢迎的完全面向对象的语言。