Scala第四章学习笔记(面向对象编程)
延迟构造
DelayedInit特质是为编译器提供的标记性的特质。整个构造器被包装成一个函数并传递给delayedInit方法。
trait DelayedInit {
def deayedInit(x : Unit) : Unit
}
这个方法接受一个函数对象,函数对象里包含了全部的一般的构造器逻辑
trait App extends DelayedInit{ var x : Option[Function0[Unit]] = None override def delayedInit(cons : => Unit){ x = Some(() => cons) } def main(args : Array[String]) : Unit = x.foreach(_()) }
如上代码,它定义了一个Option x用来容纳构造器行为。覆盖了delayedInited方法。在X变量里存放构造器逻辑,main方法去执行存放在x变量里的构造器逻辑。
DelayedInit特质可以用于延迟整个对象的构造过程,直到所有属性都被注入完成。
多重继承
为特质的抽象方法提供空实现
首先创建一个SimulationEntity类,只有一个handleMesaage方法,用于接收一个消息对象和一个上下文对象
trait SimulationEntity{
def handleMessage(msg : SimulationMessage,ctx : SimulationContext) : Unit
}
模拟系统设计为让每个节点通过在上下文传递的消息。当一个实体收到消息时,它更新自身当前状态并发送对应于该状态的消息。上下文也可以用来在后面的模拟中(对各实体的行为)进行调度。
下来定义一个简单的NetworkEntity特质和对应的行为(behavior)
trait NetworkEntity{ def getMacAddress(ip : String) : String def hasIpAddress(addr : String) : Boolean def handleMessage(msg : SimulationMessage,ctx : Simulation) : Unit = msg match{ case PingRequest(ip,sender) if hasIpAddress(ip) => ctx respond(sender,PingResponse(getMacAddress(ip))) case _=> super.handleMessage(msg) } }
尝试空实现的特质
trait MixableParent extends SimulationEntity{ override def handleMessage(msg : SimulationMessage, ctx : SimulationContext) : Unit = {} } trait NetWorkENntity exntends MixableParent{ def getMacAddress(ip : String) : String def hasIpAddress(addr : String ) : Boolean override SimulationContext) : Unit = msg match{ case PingRequest(ip , sender) if hasIpAddress(ip) => ctx respond(sender, PingResponse(getMacAddress(ip), this)) case _=> super.handleMessage(msg,ctx) } } class Router extends SimulationEntity{ override def handleMessage(msg : SimulationMessage, case Test(x) => println("YAY!" + x) case _=> } }
和Simulation类交互
val rtr = new MixableParent with Router with DummyNetworkEntity rtr.handleMessage(Test(5),null) val ctx = new SimulationContext{ override def respond(entity : SimulationEntity,msg : SimulationMessage ) : Unit = { println("Sending " + msg + " to " + entity) } } rtr.handleMessage(PingRequest("HAI",rtr),ctx)
所以在通过特质创建可混入的层级结构时,需要确保有一个特质可以假定为父类的"混入点(you have a "mixin" point that traits can asuume as parent")
组合可以包含继承
由于Java不支持多重继承,因此当子类需要组合两个类的行为时,只能继承其中一个,而不得不重新实现另一个。
那么下述案例 基于继承来组合Logger 和 DataAccess
trait logger{ def log(category : String , msg : String ) : Unit = { println(msg) } } traqit DataAccess{ def query[A](in : String) : A = { ... } } trait LoggedDataAccess extends DataqAccess with Logger{ def query[A](in : String) : A = { log("QUERRY", in) super.query(in) } }
好不习惯。。。学的太尼玛痛苦了T T