Java Scala中的类、对象、特征、密封特征
我来自Java Scala中的类、对象、特征、密封特征,java,scala,oop,functional-programming,Java,Scala,Oop,Functional Programming,我来自OOP背景,想澄清我对Scala中的对象、类、特征、密封特征和案例类的看法,我将目前为止对它的理解写在下面: 我们创建对象,当我们想在其中编写一些实用程序函数时,我们可以直接访问它,而不需要使用“new”关键字,比如Java中的“Static”类 我们创建类,当我们为动词表示一个对象进行编码时,它的行为与我们在Java中为类编码时一样,我们使用“new”关键字对其进行实例化 当我们想在Java中编写与抽象类相同的代码时,我们创建了Trait 当我们想要实现Java中相同枚举的功能时,我们创
OOP
背景,想澄清我对Scala
中的对象
、类
、特征
、密封特征
和案例类
的看法,我将目前为止对它的理解写在下面:
我们创建对象
,当我们想在其中编写一些实用程序函数时,我们可以直接访问它,而不需要使用“new”关键字,比如Java中的“Static”类
我们创建类
,当我们为动词表示一个对象进行编码时,它的行为与我们在Java中为类编码时一样,我们使用“new”关键字对其进行实例化
当我们想在Java
中编写与抽象类相同的代码时,我们创建了Trait
当我们想要实现Java中相同枚举的功能时,我们创建了Sealed Trait
我们创建了Case类
,我们可以预期这个类将来可以用于模式匹配,类似于Java中的instanceOf
我对所有这些的理解正确吗?如果你用面向对象的眼光审视这些事实,你所陈述的大部分事实或多或少是正确的。但我们对他们还有更多的要求 对象 从函数编程的角度来看,Scala中的对象可以看作是模块。它们确实用于聚合类似的函数,您称之为“效用函数”。但它们也有额外的含义 一个
对象
可以看作是一个单例对象,因为您可以拥有一个继承了特定特征
或类
的对象
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中查看特征的一种方法是将其作为抽象类
。但请注意,Scala中也可以有一个抽象类
,其行为与Java中相同。那么有什么区别呢
正如评论中所指出的,几个trait
s可以混合在一起
另外,如果是完全抽象的,trait
s可以被看作是一个Java接口,也就是说,所有的方法都像Java一样是抽象的。事实上,如果您的目标是与Java的互操作,那么这就是声明接口的方法
sealed trait
只是告诉编译器除了同一文件中的类以外,不会有任何类或其他特性继承这个类或特性。正如您在case类中指出的那样,这是用于模式匹配的,因此编译器可以通过警告来判断模式匹配是否详尽。但是还要注意Scala有enum
案例类
案例类可与密封特征
一起使用,用于模式匹配。但是案例类更像是“价值类”。case
使编译器生成一堆样板代码,因此您不必这样做
您有一个自动的“伴生对象”,因此您可以使用自动生成的apply
功能在不使用new
的情况下实例化对象
您有自动的hashCode
,等于
,toString
和复制
实现。对于所有构造函数的参数,都有自动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)
仅评论“Trait”:由于您的类可以继承多个Trait(mix-ins),我不会将其与Java抽象类进行比较。您是说,我们可以在类中扩展多个Trait,但Java限制我们一次只扩展一个类?。如果是的话,还有其他区别吗?是的,你可以随心所欲地扩展你的特性。