1. 在实例对象指定混入某个trait
- 可在创建类对象时,为该对象指定混入某个trait,且只混入trait的对象才具有trait中的方法,而其他类的对象则没有;
- 在创建对象时,使用with关键字指定混入某个trait;
- 代码如下
trait LoggedTrait{
def log(msg:String) = {}
}
trait MyLogger extends LoggedTrait{
override def log(msg:String) = println("log: " + msg)
}
class PersonForMixTraitMethod(val name:String) extends LoggedTrait{
println("Hi,I'm "+ this.name)
log("sayHello method is invoked!")
}
object PersonForMixTraitMethod{
def main(args:Array[String]){
val tom = new PersonForMixTraitMethod("Tom").sayHello with MyLogger
rose.sayHello
}
}
2. trait调用链(设计模式-责任链)
- Scala中支持让类继承多个trait后,可依次调用多个trait中的同一个方法,只要让多个trait中的同一个方法,在最后都依次执行super关键字即可;
- 类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依次往左执行,形成一个调用链条;
- 这种特性非常强大,其实就是设计模式中责任链模式的一种具体实现;
- 代码如下
trait HandlerTrait{
def handle(data:String) = {
println("last one")
}
}
trait DataValidHandlerTrait extends HandlerTrait{
override def handle(data:String) = {
println("check data: " + data)
super.handle(data)
}
}
trait SignatureValidHandlerTrait extends HandlerTrait{
override def handle(data:String) = {
println("check signature: " + data)
super.handle(data)
}
}
class PersonForRespLine(val name:String) extends SignatureValidHandlerTrait with DataValidHandlerTrait{
def sayHello = {
println("Hello, " + this.name)
this.handle(this.name)
}
}
object PersonForRespline{
def main(args:Array[String]){
val p = new PersonForRespLine("tom")
p.sayHello
}
}
3. 混合使用trait的具体方法和抽象方法(设计模式-模板设计模式)
- 在trait中, 可以混合使用具体方法和抽象方法;
- 可以让具体方法依赖于抽象方法,而抽象方法则可放到继承trait的子类中区实现;
- 这种trait特性,其实就是设计模式中的模板设计模式的体现;
- 代码如下
trait ValidTrait{
def getName:String
def valid:Boolean = {
"Tom".equals(this.getNamed)
}
}
class PersonForValid(val name:String) extends ValidTrait{
def getName:String = this.name
}
object PersonForValid{
def main(args:Array[String]): Unit = {
val person = new PersonForValid("Rose")
println(person.valid)
}
}
4. trait的构造机制
- 在Scala中,trait也是有构造代码的,即在trait中,不包含在任何方法中的代码;
- 继承了trait的子类,其构造机制如下:
- 父类的构造函数先执行,class类必须放在最左边;多个trait从左向右依次执行;先构造父trait,如果多个trait继承同一个父trait,则父trait只会构造一次;所有trait构造完毕之后,子类的构造函数最后执行。
- 代码如下
class Person_One{
println("Person's constructor!")
}
trait Logger_One{
println("Logger's constructor!")
}
trait MyLogger_One extends Logger_One{
println("MyLogger's constructor!")
}
trait TimeLogger_One extends Logger_one{
println("TimeLogger's constructor!")
}
class Student_One extends Person_One with MyLogger_One with TimeLogger_One{
println("Student's constructor!")
}
object exe_one{
def main(args:Array[String]){
val student = new Student_One
}
}
5. trait继承class
- 在Scala中trait也可以继承class,此时这个class就会成为所有继承该trait的子类的超级父类。
- 代码如下
class MyUtil{
def printMsg(msg:String) = println(msg)
}
trait Logger_Two extends MyUtil{
def log(msg:String) = this.printMsg("log: " + msg)
}
class Person_Three(val name:String) extends Logger_Two{
def sayHello{
this.log("Hi,I'm " + this.name)
this.printMsg("Hello,I'm " + this.name)
}
}
object Person_Three{
def main(args:Array[String]) {
val p = new Person_Three("Tom")
p.sayHello
}
}