现象:
打开idea,构建scala文件时,会出现object、class、trait三个选项,怎么选?有什么区别?在回顾之前写的一些代码时,模仿别的工程建设相应的文件,但不知所以然,今天来总结总结。
简单点说:执行入口用object,功能性函数用class,多重继承使用trait。
解释:
object
scala 中没有 static 关键字对于一个class来说,所有的方法和成员变量在实例被 new 出来之前都是无法访问的,因此class文件中的main方法也就没什么用了,scala object 中所有成员变量和方法默认都是 static 的所以可以直接访问main方法。除此之外,object还可以扩展类:例如,
abstract class ClassName(val parameter){}
object Test extends ClassName(val parameter){}
注意:object不能提供构造器参数,也就是说object必须是无参的。
跟java对比,来看一个java的例子:这里的main函数,使用了static关键字修饰,使得new出来实例obj,可以调用dfs这个方法。
public class ClimbingStairs1 {
private int count = 0;
public void dfs(int target) {
if(target <= 2) {
this.count += target;
return;
}
dfs(target-1);
dfs(target-2);
}
public static void main(String[] args) {
ClimbingStairs1 obj = new ClimbingStairs1();
int n = 3;
obj.dfs(n);
System.out.print(obj.count);
}
}
另外,当构建好一个工程后,将其提交到集群执行时,提交目录是object所在的目录。
class(可写在object中)
在scala中,类名可以和对象名为同一个名字,该对象称为该类的伴生对象,类和伴生对象可以相互访问他们的私有属性,但是他们必须在同一个源文件内。类只会被编译,不能直接被执行,类的申明和主构造器在一起被申明,在一个类中,主构造器只有一个所有必须在内部申明主构造器或者是其他申明主构造器的辅构造器,主构造器会执行类定义中的所有语句。scala对每个字段都会提供getter和setter方法,同时也可以显示的申明,但是针对val类型,只提供getter方法,默认情况下,字段为公有类型,可以在setter方法中增加限制条件来限定变量的变化范围,在scala中方法可以访问改类所有对象的私有字段。
trait
在java中可以通过interface实现多重继承,在Scala中可以通过特征(trait)实现多重继承,不过与java不同的是,它可以定义自己的属性和实现方法体,在没有自己的实现方法体时可以认为它时java interface是等价的,在Scala中也是一般只能继承一个父类,可以通过多个with进行多重继承。
trait TraitA{}
trait TraitB{}
trait TraitC{}
object Test1 extends TraitA with TraitB with TraitC{}