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一次至多應用一個隱式轉換。在當前範圍內,如果發現通過類型轉換有助於操作、方法調用或類型轉換的成功完成,就會進行轉換。