Scala-Trait
Trait
Trait就像一个拥有部分实现的接口,可以通过with关键字混入导类中。
trait Friend {
val name: String
def listen() = println("Your friend " + name + " is listening")
}
class Animal
class Dog(val name: String) extends Animal with Friend {
override def listen = println(name + "'s listening quietly")
}
一个类混入了trait之后,可以把它的引用当做trait的引用
val comet = new Dog("Comet")
val mansBestFriend : Friend = comet
mansBestFriend.listen
选择性混入
除了可以对整个类
的混入trait,还可以选择只对类的个别实例
混入trait
class Cat(val name: String) extends Animal
val snowy = new Cat("Snowy") with riend
snowy listen
trait装饰
scala里调用的方法 会从最右边
的trait中查找。而trait中通过super
关键字调用的方法会是其左边的trait的方法。
以下代码apartmentApplication check方法的调用顺序为从右到左
1. CriminalRecordCheck check() -> super.check()
2. CreditCheck check() -> super.check()
3. Check check()
abstract class Check {
def check() : String = "Checked Application Details..."
}
trait CreditCheck extends Check {
override def check() : String = "Checked Credit..." + super.check()
}
trait CriminalRecordCheck extends Check {
override def check() : String = "Check Criminal Records..." + super.check()
}
val apartmentApplication = new Check with CreditCheck with CriminalRecordCheck
println(apartmentApplication check)
trait延迟绑定
trait如果继承了抽象基类,则通过super
调用的方法必须声明为abstract override
,表明方法实际最后的“终极”实现由混入trait的类提供。
abstract class Writer {
def writeMessage(message: String)
}
trait UpperCaseWriter extends Writer {
abstract override def writeMessage(message: String) = super.writeMessage(message.toUpperCase)
}
trait ProfanityFilteredWriter extends Writer {
abstract override def writeMessage(message: String) = super.writeMessage(message.replace("stupid", "s-----"))
}
class StringWriterDelegate extends Writer {
val writer = new java.io.StringWriter
def writeMessage(message: String) = writer.write(message)
override def toString() : String = writer.toString
}
val myWriterProfanityLast = new StringWriterDelegate with ProfanityFilteredWriter with UpperCaseWriter
隐式转换
隐式类型转换可以帮助我们扩展语言,创建专用
的词汇或语法,例如可以实现下面这样的这样的代码。
2 days ago
5 days from_now
1 首先定义一个包含dasy
方法的类
import java.util._
class DateHelper(number: Int) {
def days(when: String) : Date = {
var date = Calendar.getInstance()
when match {
case DateHelper.ago => date.add(Calendar.DAY_OF_MONTH, -number)
case DateHelper.from_now => date.add(Calendar.DAY_OF_MONTH, number)
case _ => date
}
date.getTime()
}
}
2 定义伴生对象,包含ago
和from now
变量和一个转换方法
(接收一个Int,返回一个DataHelper的实例)
object DateHelper {
val ago = "ago"
val from_now = "from_now"
implicit def convertInt2DateHelper(number: Int) = new DateHelper(number)
}
3 导入使用
import DateHelper._
val past = 2 days ago
val appointment = 5 days from_now
println(past)
println(appointment)
4 解释
导入DateHelper时,Scala会自动的找到转换器。这是因为Scala会在当前范围和导入的范围内
进行转换。Scala一次至多应用一个隐式转换。在当前范围内,如果发现通过类型转换有助于操作、方法调用或类型转换的成功完成,就会进行转换。