1.接口不会有构造器,特质可以有构造器,并且在实现类继承特质的时候,先要调用特质的构造器。
trait构造器的调用顺序小结:
class B{}
trait C extends E{}
trait D extends E{}
A extends B with C with D
(1)先调用父类构造器B
(2)继承多个trait从从左至右依次执行,先调用父trait E构造器,再调用C,再调用D构造器
(3)如果多个trait继承同一个父trait,则父trait只执行一次
(4)所有父类构造器和trait构造器执行完毕之后再执行自己的构造器A
2.接口中不能有未初始化的属性,且属性的修饰都是public static final,特质中可以有未初始化的属性变量,即抽象字段;
未初始化的属性可以有提前定义的特性,有两种方法,例如:
trait A{
val name:String//抽象字段
println("name: "+name)//特质中构造器执行的语句
}
class B extends A{
val name:String = "张三"
}
此时如果在main函数中new B的话,肯定会报错,因为new B必然先会调用特质中的构造器,而name并没有被赋值,所以会报错。有三种方法解决:
(1)class B extends {
val name:String = "张三" //提前定义在类前
} with A{}
(2)class B{}
main函数中new B的时候:
val b = new {
val name:String = "张三"//提前定义在new对象前
} with B with A
(3)利用lazy特性
trait A{
lazy val name:String = null
println("name: "+name)
}
class B extends A{
override lazy val name:String = "张三"
}
3.Java8之前接口中不能有已经实现的方法,之后可以有default方法和静态方法,特质中可以有已实现的方法也有抽象方法。
4.类实现implements多个接口,且用逗号“,”隔开,类继承extends多个trait且用with隔开。
5.Java中接口不能继承普通类,但是scala中特质可以extends class,并且该类成为所有继承trait的类的父类,例如:
class B{}
trait A extends B{}
class C extends A{}
则C是B的子类,B是C的父类
6.scala中为实例提供混入trait(只有某个对象有trait的性质,其他对象没有),Java中没有,例如:
trait A{}
trait B extends A{}
class C extends A{}
main函数中new对象时:
val c1 = new C
val c2 = new C with B//为对象c2增加了特质B的属性和函数,但c1没有
网友评论