W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
在 Scala中Trait 為重用代碼的一個基本單位。一個 Traits 封裝了方法和變量,和 Interface 相比,它的方法可以有實現,這一點有點和抽象類定義類似。但和類繼承不同的是,Scala 中類繼承為單一繼承,也就是說子類只能有一個父類。當一個類可以和多個 Trait 混合,這些 Trait 定義的成員變量和方法也就變成了該類的成員變量和方法,由此可以看出 Trait 集合了 Interface 和抽象類的優(yōu)點,同時又沒有破壞單一繼承的原則。
下面我們來看看Trait的基本用法:
定義一個 Trait 的方法和定義一個類的方法非常類似,除了它使用 trait 而非 class 關鍵字來定義一個 trait。
trait Philosophical{
def philosophize() {
println("I consume memeory, therefor I am!")
}
}
這個 Trait 名為 Philosophical。它沒有聲明基類,因此和類一樣,有個缺省的基類 AnyRef。它定義了一個方法,叫做 philosophize。這是個簡單的 Trait,僅夠說明 Trait 如何工作。
一但定義好 Trait,它就可以用來和一個類混合,這可以使用 extends 或 with 來混合一個 trait。例如:
class Frog extends Philosophical{
override def toString="gree"
}
這里我們使用 extends 為 Frog 添加 Philosophical Trait 屬性,因此 Frog 缺省繼承自 Philosophical 的父類 AnyRef,這樣 Frog 類也具有了 Philosophical 的性質(因此 Trait 也可以翻譯成特質,但后面我們還是繼續(xù)使用 Trait 原文)。
scala> val frog = new Frog
frog: Frog = green
scala> frog.philosophize
I consume memeory, therefor I am!
可以看到 Frog 添加了 Philosophical(哲學性)也具有了哲學家的特性,可以說出類似“我思故我在”的話語了。和 Interface 一樣,Trait 也定義一個類型,比如:
scala> val phil:Philosophical = frog
phil: Philosophical = green
scala> phil.philosophize
I consume memeory, therefor I am!
變量 phil 的類型為 Philosophical。
如果你需要把某個 Trait 添加到一個有基類的子類中,使用 extends 繼承基類,而可以通過 with 添加 Trait。比如:
class Animal
class Frog extends Animal with Philosophical{
override def toString="green"
}
還是和 Interface 類似,可以為某個類添加多個 Trait 屬性,此時使用多個 with 即可,比如:
class Animal
trait HasLegs
class Frog extends Animal with Philosophical with HasLegs{
override def toString="green"
}
目前為止你看到的例子中,類 Frog 都繼承了 Philosophical 的 philosophize 實現。此外 Frog 也可以重載 philosophize 方法。語法與重載基類中定義的方法一樣。
class Animal
trait HasLegs
class Frog extends Animal with Philosophical with HasLegs{
override def toString="green"
def philosophize() {
println("It ain't easy being " + toString + "!")
}
}
因為 Frog 的這個新定義仍然混入了特質 Philosophize,你仍然可以把它當作這種類型的變量使用。但是由于 Frog 重載了 Philosophical 的 philosophize 實現,當你調用它的時候,你會得到新的回應:
scala> val phrog:Philosophical = new Frog
phrog: Philosophical = green
scala> phrog.philosophize
It ain't easy being green!
這時你或許推導出以下結論:Trait 就像是帶有具體方法的 Java 接口,不過其實它能做的更多。Trait 可以,比方說,聲明字段和維持狀態(tài)值。實際上,你可以用 Trait 定義做任何用類定義做的事,并且語法也是一樣的,除了兩點。第一點,Trait 不能有任何“類”參數,也就是說,傳遞給類的主構造器的參數。換句話說,盡管你可以定義如下的類:
class Point(x: Int, y: Int)
但下面的 Trait 定義直接報錯:
scala> trait NoPoint(x:Int,y:Int)
<console>:1: error: traits or objects may not have parameters
trait NoPoint(x:Int,y:Int)
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: