程式扎記: [Scala 小學堂] Scala Gossic : 了解更多 - 類別管理 (套件)

標籤

2016年7月4日 星期一

[Scala 小學堂] Scala Gossic : 了解更多 - 類別管理 (套件)

轉載自 這裡
前言 :
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. 在進行類別管理時, 東西別亂擺,方便別亂給,權限別亂設.

類別管理(Package) :
到目前為止所撰寫的 Scala 範例程式,都可以寫在一個.scala的檔案中,使用scala指令以直譯的方式來執行,.scala中可以包括數個類別定義,也可以包括陳述句,這方便你快速撰寫一些簡單類別或程式. 一個應用程式中會有多個類別彼此合作,也有可能由多個團隊共同分工,完成應用程式的某些功能塊,再組合在一起。一旦你程式開始要好好地管理類別,你就要為類別分門別類,而不再是一個 .scala 檔案從頭寫到尾,你要有個分門別類管理類別的方式,無論是實體檔案上的分類管理,或是程式邏輯上的分類管理. 在Scala中使用套件Package機制來管理類別,舉個例子來說,你要將 Point 類別放在 cc.openhome 套件中 :
- Point.scala 代碼 :
  1. package cc.openhome  
  2. class Point(val x: Int, val y: Int)  

若要以直譯的方式來使用這個類別,則以上的內容必須存成一個 Point.scala,並放在 cc 資料夾的 openhome 資料夾中,例如 :
  1. |workspace|  
  2.           Main.scala  
  3.           |cc|  
  4.              |openhome|  
  5.                       |Point.scala  
接著你可以如下寫個 .scala 來直譯執行,例如 Main.scala :
- Main.scala 代碼 :
  1. val x = new cc.openhome.Point(11)  

注意!套件名稱與類別名稱會結合為完全吻合名稱(Fully-qualified name),以上例來說,類別的完全吻合名稱就是 cc.openhome.Point. 直譯時,使用 scala Main.scala,scala 會去尋找對應套件設定的資料夾下,是否有對應的 .scala 檔案. 你可以使用 scalac 編譯出 .class, 例如 scalac Point.scala,這會為你自動建立 cc 資料夾與 openhome 子資料夾,然後將 Point.class 置於 openhome 資料夾中,接著你在 執行 scala 指令時,就可以使用 -classpath 或 -cp 指定類別路徑來使用編譯好的.class 總而言之,Scala 套件管理不僅是語法層面的,也是實體檔案管理的一種方式,套件名稱對應至實體資料夾名稱,類別必須放在對應的資料夾之中. 事實上,之前的 Point.scala 的撰寫方式,其實是以下撰寫方式的語法蜜糖 :
  1. package cc {  
  2.     package openhome {  
  3.         class Point(val x: Int, val y: Int)  
  4.     }  
  5. }  
由於 cc 與 openhome 套件之間,並沒有別的類別定義,所以也可以撰寫為以下的方式 :
  1. package cc.openhome {  
  2.     class Point(val x: Int, val y: Int)  
  3. }  
Scala 也允許你在同一個 .scala 中巢狀套件,例如 :
- Demo.scala 代碼 :
  1. package cc {  
  2.     package openhome {  
  3.         class Point(val x: Int, val y: Int)  
  4.     }  
  5.     package drawing {  
  6.         class Cricle(val x: Int, val y: Int, val r: Int) {  
  7.             // 不需要寫 cc.openhome.Point  
  8.             val center = new openhome.Point(x, y)  
  9.         }  
  10.     }  
  11. }  

如果你在同一個 .scala 中巢狀套件,那麼使用當中類別的方式是使用 scalac 將之編譯為 .class,scalac 會根據當中的套件資訊建立對應的資料夾,並將 .class 置入對應的資料夾中,上面的例子中,scalac 的結果如下 :
  1. |workspace|  
  2.           Demo.scala  
  3.           |cc|  
  4.              |openhome|  
  5.                       |Point.class  
  6.              |drawing|  
  7.                       |Circle.class  
注意到在上例中,在 cc.drawing 中的類別在使用到 cc.openhome.Point 類別時,並不用真的寫 cc.openhome.Point,而只要寫 openhome.Point,這是因為 cc.drawing 與 cc.openhome 的上一層套件都是 cc,因此可以省略(你要完整寫出 cc.openhome.Point 也是可以的). 但下面這個範例,使用的是哪個 Point 類別定義呢?
  1. package cc {  
  2.     package openhome {  
  3.         class Point(val x: Int, val y: Int)  
  4.     }  
  5.     package drawing {  
  6.         class Cricle(val x: Int, val y: Int, val r: Int) {  
  7.             // 這個使用的是 cc.openhome.Point   
  8.             val center = new openhome.Point(x, y)  
  9.         }  
  10.     }  
  11. }  
  12.   
  13. package openhome {  
  14.     class Point(val x: Int, val y: Int)  
  15. }  
如果你想要使用的,真的就是從最上層套件開始的 openhome.Point,而不是 cc.openhome.Point,則可以使用_root_來指定,例如 :
  1. package cc {  
  2.     package openhome {  
  3.         class Point(val x: Int, val y: Int)  
  4.     }  
  5.     package drawing {  
  6.         class Cricle(val x: Int, val y: Int, val r: Int) {  
  7.             // 這個使用的是 openhome.Point   
  8.             val center = new _root_.openhome.Point(x, y)  
  9.         }  
  10.     }  
  11. }  
  12.   
  13. package openhome {  
  14.     class Point(val x: Int, val y: Int)  
  15. }  


沒有留言:

張貼留言

網誌存檔