程式扎記: [Scala 小學堂] Scala Gossic : 了解更多 - 混入特徵 (作為規範介面的特徵)

標籤

2016年7月3日 星期日

[Scala 小學堂] Scala Gossic : 了解更多 - 混入特徵 (作為規範介面的特徵)

轉載自 這裡
前言 :
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. 特徵抽離共同的介面與實作,類別動態地繼承(extends)或具有(with)特徵.

作為規範介面的特徵 :
繼承的目的之一,在於延用父類別已有的程式碼,並重新定義不適合或增加新的定義,然後有些時候,並不適合用繼承來解決問題,尤其在單一繼承的語言中,例如在 Scala 中,一次只能繼承自一個類別,多重繼承在 Scala 中是不允許的,這使得「是一種」(is a)的關係在繼承時更為加強,例如,你繼承自鳥類,就必然「是一種」鳥. 舉個例子來說,鳥會飛,超人也會飛,但超人不會是一種鳥, 如果你只是為了飛行這個行為,讓超人去繼承鳥就不適當. 在 Scala 中,你可以定義 特徵Trait),類別可以繼承(extends)特徵 :
- Flyer1.scala 代碼 :
  1. trait Flyer {  
  2.     def fly(): Unit  
  3. }  
  4.   
  5. class Bird extends Flyer {  
  6.     def fly() = println("使用翅膀")  
  7. }  
  8.   
  9. class Superman extends Flyer {  
  10.     def fly() = println("使用超人披風")  
  11. }  
  12.   
  13. def doFly(flyer: Flyer) {  
  14.     flyer.fly()  
  15. }  
  16.   
  17. val bird = new Bird  
  18. val man = new Superman  
  19. doFly(bird)     // 顯示使用翅膀  
  20. doFly(man)      // 顯示使用超人披風  

你使用 trait 關鍵字來定義特徵,特徵的作用之一,就是規範必須實作的介面,也就是特徵中僅定義無任何實作程式碼的抽象方法,如果定義的是無實作的抽象方法,則繼承特徵的類別必須實作如同 Java 的 interface). 若類別本身沒有繼承自別的父類別,則可以直接繼承特徵,也就是直接使用 extends 關鍵字。上例中,doFly() 函式可接受具 Flyer 特徵的物件進行多型操作. 類別亦可繼承自某個父類別,並具有(with)指定的特徵,例如 :
- Flyer2.scala 代碼 :
  1. trait Flyer {  
  2.     def fly(): Unit  
  3. }  
  4.   
  5. class Animal  
  6.   
  7. class Bird extends Animal with Flyer {  
  8.     def fly() = println("使用翅膀")  
  9. }  
  10.   
  11. val bird = new Bird  
  12. bird.fly()            // 顯示使用翅膀  

一個類別可以具有多個特徵,例如 :
- SeaPlane.scala 代碼 :
  1. trait Flyer {  
  2.     def fly(): Unit  
  3. }  
  4.   
  5. trait Sailer {  
  6.     def cruise(): Unit  
  7. }  
  8.   
  9. class Vehicle  
  10.   
  11. class SeaPlane extends Vehicle with Flyer with Sailer {  
  12.     def fly() = println("使用螺旋槳")  
  13.     def cruise() = println("航行")  
  14. }  

特徵可以繼承自另一個特徵,例如 :
- Submarine.scala 代碼 :
  1. trait Sailer {  
  2.     def cruise(): Unit  
  3. }  
  4.   
  5. trait Diver extends Sailer {  
  6.     def dive(): Unit  
  7. }  
  8.   
  9. class Submarine extends Diver {  
  10.     def cruise() = println("航行")  
  11.     def dive() = println("潛水")  
  12. }  

如果要繼承多個特徵,則特徵之間亦使用 with 結合,例如 :
trait A
trait B
trait C extends A with B


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!