
- Scala 教程
- Scala - 首頁
- Scala - 概述
- Scala - 特性
- Scala - 環境設定
- Scala - 構建工具 (SBT)
- Scala - 基本語法
- 資料型別和變數
- Scala - 資料型別
- Scala - 變數
- Scala - 字串
- Scala - 陣列
- Scala 運算子
- Scala - 運算子
- Scala - 算術運算子
- Scala - 關係運算符
- Scala - 邏輯運算子
- Scala - 位運算子
- Scala - 賦值運算子
- Scala 條件語句
- Scala - IF ELSE
- Scala 迴圈語句
- Scala - 迴圈語句
- Scala - while 迴圈
- Scala - do-while 迴圈
- Scala - for 迴圈
- Scala - break 語句
- Scala 類和物件
- Scala - 類和物件
- Scala - 訪問修飾符
- Scala 方法和函式
- Scala - 函式
- Scala - 按名稱呼叫函式
- Scala - 帶有名稱引數的函式
- Scala - 帶有可變引數的函式
- Scala - 遞迴函式
- Scala - 預設引數值
- Scala - 高階函式
- Scala - 巢狀函式
- Scala - 匿名函式
- 部分應用函式
- Scala - Currying 函式
- Scala 集合
- Scala - 集合
- Scala - 列表
- Scala - 集合
- Scala - 對映
- Scala - 元組
- Scala - 迭代器
- Scala - 選項
- Scala 模式匹配
- Scala - 模式匹配
- Scala - 異常處理
- Scala - 提取器
- Scala - 正則表示式
- Scala 檔案 I/O
- Scala - 檔案 I/O
- Scala 高階概念
- Scala - 閉包
- Scala - 特性
- Scala 有用資源
- Scala - 快速指南
- Scala - 線上編譯器
- Scala - 有用資源
- Scala - 討論
Scala - 特性
特性封裝了方法和欄位的定義,然後可以透過將它們混合到類中來重用。與類繼承不同,在類繼承中每個類都必須從一個超類繼承,一個類可以混合任意數量的特性。
特性用於透過指定支援方法的簽名來定義物件型別。Scala 還允許特性被部分實現,但特性不能有建構函式引數。
特性定義看起來就像類定義,只是它使用關鍵字trait。以下是特性的基本示例語法。
語法
trait Equal { def isEqual(x: Any): Boolean def isNotEqual(x: Any): Boolean = !isEqual(x) }
此特性包含兩個方法isEqual 和 isNotEqual。在這裡,我們沒有為 isEqual 提供任何實現,而另一個方法有其實現。擴充套件特性的子類可以為未實現的方法提供實現。因此,特性非常類似於我們在 Java 中擁有的抽象類。
讓我們假設一個特性Equal包含兩個方法isEqual() 和 isNotEqual() 的示例。特性Equal包含一個已實現的方法,即isEqual(),因此當用戶定義的類Point擴充套件特性Equal時,應在Point類中提供isEqual()方法的實現。
這裡需要了解 Scala 的兩個重要方法,它們在下面的示例中使用。
obj.isInstanceOf [Point] 用於檢查 obj 和 Point 的型別是否相同。
obj.asInstanceOf [Point] 表示透過獲取物件 obj 型別並將其作為 Point 型別返回來進行精確轉換。
嘗試以下示例程式來實現特性。
示例
trait Equal { def isEqual(x: Any): Boolean def isNotEqual(x: Any): Boolean = !isEqual(x) } class Point(xc: Int, yc: Int) extends Equal { var x: Int = xc var y: Int = yc def isEqual(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == y } object Demo { def main(args: Array[String]) { val p1 = new Point(2, 3) val p2 = new Point(2, 4) val p3 = new Point(3, 3) println(p1.isNotEqual(p2)) println(p1.isNotEqual(p3)) println(p1.isNotEqual(2)) } }
將上述程式儲存到Demo.scala中。以下命令用於編譯和執行此程式。
命令
\>scalac Demo.scala \>scala Demo
輸出
true false true
值類和通用特性
值類是 Scala 中一種新的機制,用於避免分配執行時物件。它包含一個只有一個val引數的主建構函式。它僅包含方法 (def),不允許使用 var、val、巢狀類、特性或物件。值類不能被另一個類擴充套件。這可以透過使用 AnyVal 擴充套件值類來實現。自定義資料型別的型別安全,沒有執行時開銷。
讓我們以值類 Weight、Height、Email、Age 等為例。對於所有這些示例,不需要在應用程式中分配記憶體。
值類不允許擴充套件特性。為了允許值類擴充套件特性,引入了通用特性,它擴充套件了Any。
示例
trait Printable extends Any { def print(): Unit = println(this) } class Wrapper(val underlying: Int) extends AnyVal with Printable object Demo { def main(args: Array[String]) { val w = new Wrapper(3) w.print() // actually requires instantiating a Wrapper instance } }
將上述程式儲存到Demo.scala中。以下命令用於編譯和執行此程式。
命令
\>scalac Demo.scala \>scala Demo
輸出
它將為您提供 Wrapper 類的雜湊碼。
Wrapper@13
何時使用特性?
沒有硬性規定,但以下是一些需要考慮的指導原則:
如果行為不會被重用,則將其設為具體類。畢竟它不是可重用的行為。
如果它可能在多個不相關的類中重用,則將其設為特性。只有特性才能混合到類層次結構的不同部分。
如果要從 Java 程式碼中繼承它,請使用抽象類。
如果計劃以編譯的形式分發它,並且您期望外部組編寫從中繼承類的類,那麼您可能會傾向於使用抽象類。
如果效率非常重要,請傾向於使用類。