Scala中面向对象编程之trait下篇、在实例对象指定混入某个trait、trait调用链、混合使用 trait 的具体方法和抽象方法、trait的构造机制、trait 继承 class 14

1. 在实例对象指定混入某个trait

  • 可在创建类对象时,为该对象指定混入某个trait,且只混入trait的对象才具有trait中的方法,而其他类的对象则没有;
  • 在创建对象时,使用with关键字指定混入某个trait;
  • 代码如下
trait LoggedTrait{
	//该方法为实现的具体方法
	def log(msg:String) = {}
}
trait MyLogger extends LoggedTrait{
	//覆盖log()方法
	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]){
		//创建对象时,混入了MyLogger接口
		val tom = new PersonForMixTraitMethod("Tom").sayHello with MyLogger
		//调用sayHello()方法时,sayHello()方法中调用MyLogger的log()方法。
		rose.sayHello
		//结果为:Hi,I'm Rose
		//结果为:log: sayHello method is invoked!
	}
}

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
		//执行结果:
		//Hello,tom --> class PersonForRespLine自带的sayHello()方法
		//check data:tom --> DataValidHandlerTrait接口中的handle()方法
		//check signature:tom --> SignatureValidHandlerTrait接口中的handle()方法
		//last one
	}
}

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)//false
	}
}

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
		//执行结果为:
		//		Person's constructor!
		//      Logger's constructor!
		//      MyLogger's constructor!
		//      TimeLogger's contructor!
		//      Student's constructor!
	}
}

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
		//执行结果
		// log:Hi,I'm Tom
		// Hello,I'm Tom
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值