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 时位于隐式范围内,因为TT 的子类型是类型的一部分X。这用于查找隐式视图和隐式参数。【参考方案3】:

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

【讨论】:

以上是关于Scala - 类就足够了吗?的主要内容,如果未能解决你的问题,请参考以下文章

Scala中的类继承关系

Scala路线图:跳过2.14,明年上Scala 3

[转]scala执行linux命令

Scala 二进制序列化库

符合给定条件的 Scala/Java ORM

如何使用分隔符 ^|^ 将数据文件加载到 spark scala 中?