trait
* 类似于java中的interface
* 类可以继承多个trait,使用关键字extends,与java不同的是,不是使用implement关键字
* scala中对类只能单继承,对trait可以多继承
trait TraitDemo01 { //抽象方法 def say } trait TraitDemo01_01 { //抽象方法 def sayHi(context:String):Unit } //继承多个trait时,使用with进行连接 class Clazz extends TraitDemo01 with TraitDemo01_01 { //复写接口TraitDemo01中的抽象方法,可以不用带override关键字 def say = { println("world") } //复写接口TraitDemo01_01中的抽象方法 def sayHi(context:String):Unit = { println(s"hello $context") } } object Clazz { def main(args: Array[String]): Unit = { val t1 = new Clazz t1.say t1.sayHi("world") } } 运行结果: world hello world
trait中定义字段和方法
*trait中可以定义具体的方法和具体的字段
* 一个类继承父类和trait时,继承父类的字段实际是定义在父类中的。继承trait中定义的字段就直接被添加到该类中
trait TraitDemo02 { //非抽象字段 //var 修饰的非抽象字段,不能被重写 var name: String = "张三" //val 修饰的非抽象字段,可以被重写 val name2: String = "李四" //抽象字段,var和val修饰的字段,都能被重写 val age: Int //非抽象方法 def say = { println("hello") } } class TraitDemo0202 { val name3: String = "王五" } //继承类和trait //继承父类,父类的字段实际是定义在父类中的。继承trait,trait中定义的字段就直接被添加到Clazz2类中 class Clazz2 extends TraitDemo0202 with TraitDemo02{ override val age:Int = 12 } object Clazz2 { def main(args: Array[String]): Unit = { val p = new Clazz2 //Clazz2的类文件中,实际上添加了继承的trait的字段,即age,name,name2,而name3字段在父类的类文件中,但能访问 p.age p.name p.name2 p.name3 } }
实例对象混入trait
一个类继承了父类或trait,那么这个类就拥有父类或trait的所有非私有方法
实例对象混入trait,使用with
trait TraitDemo03 { def say = { println("hello") } } //一个类继承了父类或trait,那么这个类就拥有父类或trait的所有非私有方法 class Dog0301(var name: String, var age: Int) object Dog0301 { def main(args: Array[String]): Unit = { //没有混入trait,不能调用trait的方法 val d1 = new Dog0301("小白", 2) //为类实例对象混入trait,那么该实例就拥有trait的所有非私有方法 val d2 = new Dog0301("小黑", 3) with TraitDemo03 d2.say } }
trait也有主构造代码块,不包含在任何方法中的代码就是trait的主构造器的代码
继承了类和trait的构造机制:
* 1,先执行父类的构造代码块
* 2,执行trait的构造代码块,如果有多个trait,从左往右执行。
* 如果多个trait继承了同一个父trait,那么先执行父trait的构造代码块,然后执行子trait的构造代码块
* 3,最后执行自己的构造代码块
trait TraitDemo04 { println("TraitDemo04 的主构造代码块") } trait TraitDemo0401 extends TraitDemo04 { println("TraitDemo0401 的主构造代码块") } trait TraitDemo0402 extends TraitDemo04 { println("TraitDemo0402 的主构造代码块") } class Clazz04 { println("Clazz04 的主构造代码块") } class Clazz0401 extends Clazz04 with TraitDemo0401 with TraitDemo0402 { println("Clazz0401 的主构造代码块") } object Clazz0401 { def main(args: Array[String]): Unit = { val o = new Clazz0401 } } 运行结果: Clazz04 的主构造代码块 TraitDemo04 的主构造代码块 TraitDemo0401 的主构造代码块 TraitDemo0402 的主构造代码块 Clazz0401 的主构造代码块