如果你用OOP的眼光来研究它们,你对你所说的大多数事实或多或少是正确的。但我们对他们还有更多。
对象
Scala中的对象可以从函数式编程的角度看作是模块。它们确实用于聚合您称为“实用程序函数”的类似类型的函数。但它们也有其他含义。
可以将其视为单例对象,因为您可以拥有 继承特定 或 .object
object
trait
class
trait Bird
object Duck extends Bird
您还有伴随对象的概念。这是一个具有与该类相关的模块函数的对象,您甚至可以从该类中引用该对象的成员。private
class Dog {
def eat(food: Food) = Dog.preferredFoods.contains(food)
}
object Dog {
private val preferredFoods = List(Ribeye, DogFood, Banana)
def walk(dog: Dog) = ???
}
类
你对课程的看法是正确的。它们与Java概念非常接近。
特性
在 Scala 中查看 a 的一种方法是作为 .但请注意,您也可以在Scala中拥有一个,其行为与Java中的行为相同。那么有什么区别呢?trait
abstract class
abstract class
正如注释中所指出的,可以将几个s混合在一起。trait
如果它是完全抽象的,那么s也可以被视为Java,也就是说所有方法都是抽象的,就像Java一样。实际上,如果您的目标是与 Java 互操作,这就是声明 .trait
interface
interface
A 只是一种告诉编译器,除了同一文件中的类或其他特征之外,您不会有任何继承此类或其他特征的方法。正如您所指出的关于 case 类时,这起到了模式匹配的目的,因此编译器能够通过警告来判断模式匹配是否详尽无遗。但也要注意斯卡拉有.sealed trait
enum
案例类
Case 类可以与 一起使用,以实现模式匹配。但 a 更像是一个“值类”。这使得编译器生成一堆样板代码,因此您不必这样做。sealed trait
case class
case
您有一个自动的“伴随对象”,因此您可以使用自动生成的函数在没有 的情况下实例化对象。new
apply
您有自动 、 和 实现。并且所有构造函数的参数都有自动 s。hashCode
equals
toString
copy
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)