Scala中的类,对象,特征,密封特征

时间:2015-03-23 09:53:07

标签: java scala oop functional-programming

我来自OOP背景,并希望明确我对ObjectClassesTraitSealed TraitCase Classes的看法Scala,我写下目前为止我对它的理解:

我们创建Object,当我们想要在其中编写一些实用程序函数时,我们可以直接访问它,而不使用Java中的“new”关键字作为“静态”类。

我们创建Classes,当我们编写动词时意味着一个对象,它的行为封装与我们为Java中的类编码相同,我们使用“new”关键字对其进行实例化。

当我们想要在Trait中编写与抽象类相同的代码时,我们会创建Java

当我们想要在Java中实现与Enum相同的功能时,我们创建Sealed Trait

我们创建Case classes时,我们可以预期此类可以在将来用于模式匹配,类似于Java中的instanceOf。

我的理解是否正确?

1 个答案:

答案 0 :(得分:19)

如果你用OOP眼睛观察它们,你或多或少都对你所陈述的大部分事实都是正确的。但是我们还有更多的东西。

对象

Scala中的对象可以从功能编程角度看作 modules 。它们的确用于聚合您称为“效用函数”的类似的kinded函数。但它们也有其他含义。

可以将object视为单个对象,因为您可以拥有一个继承特定objecttrait的{​​{1}}。

class

您还拥有伴侣对象的概念。这是一个具有与该类相关的模块函数的对象,您甚至可以从该类中引用该对象的trait Bird object Duck extends Bird 成员。

private

你对课程是正确的。它们与Java概念非常接近。

性状

在Scala中查看class Dog { def eat(food: Food) = Dog.preferredFoods.contains(food) } object Dog { private val preferredFoods = List(Ribeye, DogFood, Banana) def walk(dog: Dog) = ??? } 的一种方法是trait。但请注意,Scala中也可以有abstract class,其行为与Java相同。那有什么区别?

正如评论中所指出的,可以将几个abstract class混合在一起。

如果trait完全是抽象的,那么trait也可以被视为Java interface,即所有方法都是抽象的,就像Java一样。实际上,如果您的目标是使用Java进行互操作,那就是声明interface的方法。

sealed trait只是一种告诉编译器你不会有任何类或其他特性继承这个特性的方法,除了同一个文件中的类。当你指出案例类时,这就是模式匹配的目的,因此编译器能够通过警告判断模式匹配是否详尽无遗。但另请注意,Scala有enum

案例类

案例类可以与sealed trait一起用于模式匹配。但是case class更像是一个“价值类”。 case使编译器生成一堆样板代码,因此您不必这样做。

您有一个自动“伴侣对象”,因此您可以使用自动生成的new功能实例化不带apply的对象。

您有自动hashCodeequalstoStringcopy实施。并且您对所有构造函数的参数都有自动val

scala> case class Room(area: Int)
defined class Room

scala> var r = Room(16)
r: Room = Room(16)

scala> r.hashCode
res2: Int = 1313771839

scala> r == Room(16)
res3: Boolean = true

scala> r == Room(15)
res4: Boolean = false

scala> r.toString
res5: String = Room(16)

scala> r.area
res6: Int = 16

scala> case class Point(x: Int, y: Int)
defined class Point

scala> val p = Point(1, 1)
p: Point = Point(1,1)

scala> val p1 = p.copy(y = 0)
p1: Point = Point(1,0)