Scala學習筆記5--Trait

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章