Scala - 类就足够了吗?
Posted
技术标签:
【中文标题】Scala - 类就足够了吗?【英文标题】:Scala - are classes sufficient? 【发布时间】:2011-03-08 21:05:15 【问题描述】:来自 Java,我对 scala 的类/对象区别感到困惑。 请注意,我不要求形式上的区别;有足够的 网络上的参考资料解释了这一点,并且有相关的问题 SO。
我的问题是:
-
为什么scala的设计者
选择让事情变得更多
复杂(与 Java 或
C#)?我有什么缺点
期待我是否忽略这种区别
并且只声明类?
谢谢。
【问题讨论】:
您为什么认为 Scala 采用的方法更加“复杂”?在使用每种语言之后,Scala 的解决方案是迄今为止最简单的,尤其是在继承和子类型发挥作用时。 【参考方案1】:Scala 没有任何带有标准类的静态方法的概念,因此在这些场景中您必须使用对象。有趣的文章在这里提供了一个很好的介绍:
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-3
(向下滚动到 Scala 的静态排序)
【讨论】:
【参考方案2】:Java 类包含两种完全不同类型的成员——实例成员(例如BigDecimal.plus
)和静态成员(例如BigDecimal.valueOf
)。在 Scala 中,只有 个实例成员。这实际上是一种简化!但这留下了一个问题:我们将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 关键字为您提供了一个单例类(无论如何都是在底层),并且是 Scala 对静态成员的替代品。 请注意,如果您有一个名为Something
的类和一个名为 Something
的对象(在同一个包中),那么这两个是链接的 - 对象是 companion object 的类,两者可以看到彼此的私有成员。与 Java 相比:将类中的方法视为实例方法,将对象中的方法视为属于该类的静态方法。
好点,杰斯珀。此外,类或特征T
的伴生对象T
在搜索隐式值类型X
时位于隐式范围内,因为T
或T
的子类型是类型的一部分X
。这用于查找隐式视图和隐式参数。【参考方案3】:
看待它的一种方式是这样。一个执行程序由一组对象和线程组成。线程在对象的上下文中执行代码——即总是有一个线程正在其中执行的“this”对象。这是对 Java 的简化,因为在 Java 中并不总是有“this”。但是现在有一个鸡/蛋的问题。如果对象由线程创建并且线程在对象内执行,那么最初在其中执行的第一个线程是什么对象。在程序执行开始时必须存在一组非空对象。这些是使用object
关键字声明的对象。
【讨论】:
以上是关于Scala - 类就足够了吗?的主要内容,如果未能解决你的问题,请参考以下文章