Scala(五) class,trait,object,case class
Scala中类的写法与C++很像。
先看个普通类的例子
结果
scala有个比较奇怪的点,在它的一个普通的类中需要明确地给出变量的定义,而不能只是声明。普通的类之外,scala也有虚类,只有在虚类种才能只声明变量而不定义。就像下面这样:
Scala的类比较特别的东西是它的继承方式,不是直接继承自某个父类,而是引用trait,这样的好处的可以避免C++中多继承时候一些问题。trait本身跟一个class没有区别。比如我在前面那个individual的类加上关于ta喜欢的食物和能不能吃辣的描述。
引用这个trait的方法:
结果
IDEA这个IDEA比较贴心地在昨天行号旁用一些不同类型的小标记和箭头标出了定义继承来的trait中变量的位置。
具体来说就是要把trait中的内容重新定义一下。这里要注意两点:
1.trait中每个内容都要重新定义,哪怕用不上,像图中的food2那用直接给个_做占位符都行,都要明确定义出来。
2.trait中已经定义过的东西需要加上override来在类中重新定义,就像图中的函数can_tolerate_spice_or_not 。 trait中只声明没定义的东西不用override。
要继承多个trait的方法就是extend trait1 with trait2 with trait3,这是比较好理解的。
接下来谈谈object。
object与class的不同:
1.object是个单例模式的对象。所以在形式上,object可以看起来不实例化直接取出其中的内容。但实际上object是在第一次编译的时候就实例化了一个单例对象。
2.object内容上与class只有一点不同,就是object可以放静态变量,回忆一下c++,静态变量也就是独立于实例化对象的变量。
object常见的用法是给它取一个与某一个class一样的名字,作为class的伴随object。这样做的目的有两个。
(1)为class保存静态变量。
前面提到,scala中class不能存静态变量,但是一个class总要有静态变量啊。scala搞了一个特别的机制,让object为class保存静态变量呢,如何做呢,只要让object用与class一样的名字就可以了。比如可以看下面这个例子。同名的object和class可以直接调用互相体内的所有变量。
(2)在伴随object中添加apply方法,从而简化实例化的过程。比如看下面
case class是为了用scala的match case方法来匹配这个对象(咱就想想,为啥这个特性叫做case class呢,case的来源就是match语句里的case)
模式匹配的功能,很像C++中的switch case语句,但更加强大,强大的地方在于可以在用于提取类中的参数。这种功能有个帅气的名字叫模式匹配。
下面写了个简单的例子:
看,把watermelon类对象的参数提取出来了。
多说一句,case class除了可以用匹配模式外,还多了一个特点就是会默认配上一个companion object,里面有默认的apply方法,所以这张图的例子中我就可以看起来不用new地实例化对象。
这么看,case class是class功能上的一个加强,并且没有什么坏处,这么一想,以后直接把所有class都声明成case class好了。
这部分以后还要修改。