[英]Class, Object, Trait, Sealed Trait in Scala
我来自OOP
背景,并希望清除我对Scala
Object
, Classes
, Trait
, Sealed Trait
和Case Classes
想法,我在下面写下我对它的理解到目前为止:
我们创建Object
时,我们想要在其中编写一些实用程序函数,我们可以直接访问它,而不使用像Java中的“静态”类这样的“new”关键字。
我们创建Classes
,当我们编写动词时意味着一个对象,它的行为封装与我们为Java中的类编码相同,我们使用“new”关键字对其进行实例化。
当我们想要编写与Java
抽象类相同的代码时,我们创建Trait
。
当我们想要在Java中实现与Enum相同的功能时,我们创建了Sealed Trait
。
我们创建Case classes
时,我们可以预期此类可以在将来用于模式匹配,类似于Java中的instanceOf。
我的理解对所有这些都是正确的吗?
如果你用OOP眼睛观察它们,你或多或少都对你所陈述的大部分事实都是正确的。 但我们对他们有更多。
Scala中的对象可以从Functional Programming透视图中看作模块 。 它们的确用于聚合您称为“效用函数”的类似的kinded函数。 但它们也有其他含义。
object
可以看作是单个对象,因为您可以拥有一个继承特定trait
或class
的object
。
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中查看trait
一种方法是作为abstract class
。 但请注意,您还可以在Scala中使用abstract class
,其行为与Java相同。 那有什么区别?
正如评论中所指出的,可以将几个trait
混合在一起。
如果trait
是完全抽象的,那么trait
可以被视为Java interface
,即所有方法都是抽象的,就像Java一样。 实际上,如果你的目标是使用Java,那就是声明interface
。
sealed trait
只是告诉编译器除了同一文件中的那些之外你不会有任何继承这个特性的类或其他特征的方法。 当你指出案例类时,这就是模式匹配的目的,因此编译器能够通过警告判断模式匹配是否详尽无遗。 但也请注意Scala有enum
。
案例类可以与sealed trait
一起使用以用于模式匹配。 但case class
更像是“价值类”。 该case
使编译器生成一堆样板代码,因此您不必这样做。
您有一个自动“伴侣对象”,因此您可以使用自动生成的apply
函数实例化没有new
对象的对象。
你有自动hashCode
, equals
, toString
和copy
实现。 并有自动val
所有构造函数的参数s。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.