来自Java我对scala的类/对象的区别感到困惑。 请注意,我不要求正式的区别;网上有足够的 参考资料解释了这一点,并且在 SO上有相关的问题。斯卡拉 - 足够的类?
我的问题是:
- 为什么斯卡拉 的设计师选用使事情变得更加复杂 (相比于Java或 C#)?如果我忽略 并声明只有类,我期望 有什么缺点?
谢谢。
来自Java我对scala的类/对象的区别感到困惑。 请注意,我不要求正式的区别;网上有足够的 参考资料解释了这一点,并且在 SO上有相关的问题。斯卡拉 - 足够的类?
我的问题是:
谢谢。
Scala没有任何标准类的静态方法的概念,所以在这些场景中你必须使用对象。这里有趣的文章提供了一个很好的介绍:
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-3
(向下滚动到Scala的排序-的静)
Java类包含两个完全不同类型的成员 - 实例成员(如BigDecimal.plus
)和静态成员(如BigDecimal.valueOf
)。在斯卡拉,有只有实例成员。这实际上是一种简化!但是,它会留下一个问题:我们在哪里放置像valueOf
这样的方法?这就是对象有用的地方。
class BigDecimal(value: String) {
def plus(that: BigDecimal): BigDecimal = // ...
}
object BigDecimal {
def valueOf(i: Int): BigDecimal = // ...
}
可以认为这是匿名类的声明和其单实例:
class BigDecimal$object {
def valueOf(i: Int): BigDecimal = // ...
}
lazy val BigDecimal = new BigDecimal$object
当阅读Scala代码,关键的是从值区分的类型。我已经将IntelliJ配置为蓝色类型。
val ls = List.empty[Int] // List is a value, a reference the the object List
ls: List[Int] // List is a type, a reference to class List
Java还具有另一个程度的复杂性,在Scala中被删除 - 字段和方法之间的区别。接口上不允许使用字段,除非它们是静态的和最终的;方法可以被重写,如果在子类中重新定义,则字段将被隐藏。 Scala消除了这种复杂性,只向程序员公开方法。如果你没有声明任何对象,你的程序可能永远不会运行,因为你在Scala中定义相当于public static void main(String... args) {}
,你至少需要一个对象!
object关键字为您提供了一个singleton类(无论如何),并且是Scala对静态成员的替代。 – apollodude217 2010-06-27 20:42:37
请注意,如果您有一个名为'Something'的类和一个名为'Something'的对象(在同一个包中),那么这两个是链接的 - 该对象是该类的*伴侣对象*,两者可以看到彼此的私人成员。与Java比较:将类中的方法视为实例方法,将对象中的方法视为属于该类的静态方法。 – Jesper 2010-06-27 20:55:14
好点,Jesper。另外,当给定T或T的子类型是类型的一部分时,当搜索隐式值'X'时,类或特征“T”的伴随对象“T”处于隐式范围'X'。这用于查找隐式视图和隐式参数。 – retronym 2010-06-27 21:37:21
查看它的一种方法是这样的。执行程序由对象和线程的社区组成。线程在对象的上下文中执行代码 - 即总是有一个线程在其内执行的“this”对象。这是Java的简化,因为在Java中,并不总是有“this”。但现在有一个鸡/蛋问题。如果对象是由线程创建的,并且线程在对象内执行,那么最初在其中执行的第一个线程是什么对象。程序执行开始时必须存在一组非空对象。这些是使用object
关键字声明的对象。
你为什么认为斯卡拉的做法更复杂?使用各种语言后,Scala的解决方案是迄今为止最简单的解决方案,尤其是在继承和子类型发挥作用时。 – soc 2011-08-07 14:09:04