Scala Trait 的基本概念

2018-09-28 18:19 更新

Trait 的基本概念

在 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)
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號