2010-06-27 103 views
7

来自Java我对scala的类/对象的区别感到困惑。 请注意,我不要求正式的区别;网上有足够的 参考资料解释了这一点,并且在 SO上有相关的问题。斯卡拉 - 足够的类?

我的问题是:

  1. 为什么斯卡拉 的设计师选用使事情变得更加复杂 (相比于Java或 C#)?如果我忽略 并声明只有类,我期望 有什么缺点?

谢谢。

+1

你为什么认为斯卡拉的做法更复杂?使用各种语言后,Scala的解决方案是迄今为止最简单的解决方案,尤其是在继承和子类型发挥作用时。 – soc 2011-08-07 14:09:04

回答

23

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) {},你至少需要一个对象!

+0

object关键字为您提供了一个singleton类(无论如何),并且是Scala对静态成员的替代。 – apollodude217 2010-06-27 20:42:37

+3

请注意,如果您有一个名为'Something'的类和一个名为'Something'的对象(在同一个包中),那么这两个是链接的 - 该对象是该类的*伴侣对象*,两者可以看到彼此的私人成员。与Java比较:将类中的方法视为实例方法,将对象中的方法视为属于该类的静态方法。 – Jesper 2010-06-27 20:55:14

+1

好点,Jesper。另外,当给定T或T的子类型是类型的一部分时,当搜索隐式值'X'时,类或特征“T”的伴随对象“T”处于隐式范围'X'。这用于查找隐式视图和隐式参数。 – retronym 2010-06-27 21:37:21

0

查看它的一种方法是这样的。执行程序由对象和线程的社区组成。线程在对象的上下文中执行代码 - 即总是有一个线程在其内执行的“this”对象。这是Java的简化,因为在Java中,并不总是有“this”。但现在有一个鸡/蛋问题。如果对象是由线程创建的,并且线程在对象内执行,那么最初在其中执行的第一个线程是什么对象。程序执行开始时必须存在一组非空对象。这些是使用object关键字声明的对象。