我来自OOP背景,想澄清我对Object、Classes、Trait、Sealed Trait和Case Classes in Scala的看法,我现在写的是我对此的理解:
我们创建Object,当我们想在其中编写一些实用程序函数时,我们可以直接访问它,而不需要使用像Java中的“静态”类这样的“新”关键字。
我们创建Classes,当我们对动词表示对象进行编码时,它的行为封装与我们在Java中为类编写的代码相同,我们使用"new“关键字实例化它。
当我们想要在Trait中编写与抽象类相同的代码时,我们会创建Java。
当我们希望在Java中实现相同的Enum功能时,我们会创建Sealed Trait。
我们创建Case classes时,可以预期这个类将来可以用于模式匹配,类似于Java中的instanceOf。
我对这一切的理解正确吗?
发布于 2015-03-23 13:19:24
如果你用客观的眼光去观察这些事实,那么你所陈述的大部分事实或多或少都是正确的。但我们还有更多。
对象
从函数式编程的角度来看,Scala中的对象可以看作模块。它们确实用于聚合类似的类函数,您称之为“实用函数”。但它们也有更多的含义。
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是完全抽象的,那么它可以被看作是interface,也就是说,所有方法都是抽象的,就像Java一样。事实上,如果您是针对与Java的互操作,那么这就是声明interface的方法。
sealed trait只是告诉编译器,除了同一文件中的类或其他特征之外,您不会有任何继承此类或其他特征的方法。正如您在case类中指出的那样,这起到了模式匹配的作用,因此编译器能够判断模式匹配是否是详尽无遗的,并发出警告。但也要注意Scala有enum。
案例类
Case类可以与sealed trait一起使用,用于模式匹配。但是case class更像是一个“值类”。case让编译器生成一堆样板代码,这样您就不必这样做了。
您有一个自动的“伙伴对象”,因此您可以使用自动生成的new函数实例化对象而不使用apply。
您有自动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)https://stackoverflow.com/questions/29207230
复制相似问题