scala面向对象之trait
為什么80%的碼農都做不了架構師?>>> ??
特質(trait),像是Java中接口(interface)的存在。這個大概是在以后詳說吧。object可以擴展類,以及一個或多個特質,其結果是一個擴展了指定類以及特質的類的對象,同時擁有在對象定義中給出的所有特性。一個有用的使用場景是給出可被共享的缺省對象。不是太理解這一部分,先放在這里吧。
Java程序通常從一個public類的main方法開始。而在Scala中,程序從對象的main方法開始,方法的類型是?Array[String]?=>?Unit。
在Scala中并沒有枚舉類型,但在標準類庫中提供了Enumeration類來產出枚舉。擴展Enumeration類后,調用Value方法來初始化枚舉中的可能值。
object TrafficLightColor extends Enumeration {
? val Red, Yellow, Green = Value
// 是下面代碼的簡寫,Value方法每次返回內部類Value的新實例
? val Red = Value
? val Yellow = Value
? val Green = Value
}
內部類Value實際上是一個抽象類,真正創建的是Val。因為實際上是Val,所以可以為Value傳入id和name。
val Red = Value(0, "Stop")
val Yellow = Value(10) // name為"Yellow"
val Green = Value("Go") // id為11
如果不指定,id就是在前一個枚舉值id上加一,name則是字段名。定義完成后,使用TrafficLightColor.Red這種形式類使用枚舉。枚舉的類型是TrafficLightColor.Value而不是TrafficLightColor。如果使用?importTrafficLightColor._引入枚舉值,就可以使用Red這樣簡單的形式來引用枚舉值了。
object TrafficLightColor extends Enumeration {
? val Red, Yellow, Green = Value
}
?
import TrafficLightColor._
?
def doWhat(color: Value) = {
? if (color == Red) "stop"
? else if (color == Yellow) "hurry up"
? else "go"
}
書里還提到了為枚舉值添加類型別名,但實在是看不出來需要,于是就不提了。
?
當我們為類或對象添加多個特質的時候,這些特性可以幫我們做什么,與類型系統又有什么聯系?
· 當某個對象或類混入多個相互調用的特質的時候,關于實現的方法所執行的順序是怎樣的? --> 分階段加工處理某個值的場景(調用總是從繼承的最后一個特質開始)
>>特質的構造順序:
特質也有構造器,由字段的初始化和其他的特質體語句構成
trait fileLog extends Logger{? ??
? ? val out = new PrintWriter("app.log")
? ? out.println("#"+ new Date().toString)
? ? def ?log(msg: String) {? out.println(msg); out.flush() ?}
}
#上面的這些語句都是特質構造器的一部分,這些語句在任何混入該特質的對象在構造時都會被執行
執行順序:
例:class SavingAccount extends Account with FileLog with ShortLog
Account(超類)-> Logger(第一個特質的父特質) -> FileLog(第一個特質) -> ShortLog(第二個特質)//此時她的父特質Logger已經被構造 -> SavingAccount(類)
總結:
· 首先調用超類的構造器
· 特質構造器在超類構造器之后,類構造器之前執行
· 每個特質當中,父特質先被構造
· 特質從左到右被構造
· 如果多個特質共有一個父特質,而那個父特質已經被構造,則不會被再次構造
· 所有特征被構造完畢,子類被構造
設計原則:線性化的反向 --> ? ?如果 C extends C1 with C2 則 lin(C) = C >> lin(Cn) >> ... >>lin(C2) >> lin(C1) ? ? ? ? ? ?“>>”的意思: ? ? ? ? ?"串聯并去掉重復項,右側勝出"
>>類或對象添加多個互相調用的特質
問題:需要分階段處理某個值的場景?
例:
val acc1 = new SavingAccount with ConsoleLogger with TimestampLogger with ShortLogger
acc1執行的時候會先調用ShortLogger的方法
trait TimestampLogger extends Logged
trait ShortLogger extends Logged
super.someMethod 執行哪個特質的方法,依賴于使用這些特質的對象或類給出的順序? ??
>>保證混入該特質的類都認這個類作超類
擴展類的特質:
原則:只能保證是一條線上的
例:java中類是單繼承的,在scala中也一樣
class unhappyException extends IOException with LoggedException ?// IOException 是擴展自Exception類 ?LoggedException 擴展自Exception類
class unhappyException extends IOException with JFrame ?//無法同時將JFrame和Exception作為超類
編譯器能確保所有混入該特質的類都認這個類為超類
自身類型:
例:
trait loggerException extends Logged{? ? ? ??
? ? this: Exception => //只能混入自身類型和該類型的子類
? ? def log() {?log(getMessage) ? }
}
val f = new JFrame with LoggedException ?//錯誤 JFrame不是Exception的子類型
帶有自身類型的特質和帶有超類型的特質很相似,兩種情況都能確?;烊朐撎刭|的類能夠使用某個特定類型的特性
繼承層級?
如果特質擴展自某個超類,則伴生類并不繼承這個超類,該超類會被任何實現該特質的類繼承
?
轉載于:https://my.oschina.net/wii01/blog/919733
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的scala面向对象之trait的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git 常见命令
- 下一篇: js innerHTML 改变div内容