程式扎記: [Scala 小學堂] Scala Gossic : 了解更多 - 使用繼承 (繼承)

標籤

2016年6月24日 星期五

[Scala 小學堂] Scala Gossic : 了解更多 - 使用繼承 (繼承)

轉載自 這裡 
前言 : 
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. Scala 的繼承作了一些限制,這使你在使用繼承前必須多一份思考. 

繼承 : 
你建立了一個銀行帳戶類別 : 
- Account.scala 代碼 :
  1. class Account(val id: String, val name: String) {  
  2.         protected var bal: Int= _  
  3.         def deposit(amount: Int) {  
  4.                 require(amount > 0)  
  5.                 bal += amount  
  6.         }  
  7.   
  8.         def withdraw(amount: Int) {  
  9.                 require(amount >0)  
  10.                 if(amount <= bal) {  
  11.                         bal -= amount  
  12.                 } else {  
  13.                         throw new RuntimeException("Bal not enough");  
  14.                 }  
  15.         }  
  16.   
  17.         def balance = bal  
  18.   
  19.         override def toString = "Id:\t\t" + id +  
  20.                                 "\nName:\t\t" + name +  
  21.                                 "\nBalance:\t"+bal  
  22. }  

在這個類別中,雖然沒有聲明,但你已經使用了繼承,在 Scala 中,如果你沒有指定繼承任何類別,預設就是繼承 scala.AnyRef相當於 Java 的 java.lang.Object),在上面的例子中,你重新定義了 AnyRef 的 toString 方法,傳回帳戶資料的描述字串. 
在 Scala 中,如果你要重新定義父類別中的成員,override 關鍵字是必要的,如果沒有標明 override,編譯器會告訴你,你正定義一個父類別中已經有的成員 : 


這避免你在不知情的情況下,重新定義了某個父類別的成員,override 的另一個作用是,如果你指定要 override 某個成員,但父類別中根本不存在該成員(也許是你打錯字了),編譯器也會提出警訊. 假設你為以上的類別建立了一個支票帳戶 : 
  1. class CheckingAccount(override val id: String, override val name: String)   
  2.                        extends Account(id, name) { // 繼承並呼叫父類別建構式  
  3.     private var limit: Int = 30000  
  4.       
  5.     def overdraftLimit = limit  
  6.     def overdraftLimit_=(amount: Int) {  
  7.         require(amount > 0)  
  8.         limit = amount  
  9.     }  
  10.       
  11.     override def withdraw(amount: Int) {  
  12.         require(amount > 0)  
  13.         if(amount <= bal + overdraftLimit) {  
  14.             bal -= amount  
  15.         }  
  16.         else {  
  17.             throw new RuntimeException("超出信用")  
  18.         }  
  19.     }  
  20.       
  21.     override def toString = super.toString +   
  22.                             "\nOverdraft limit:" + overdraftLimit  
  23. }  
在 Scala 中,使用 extends 來指定要繼承自哪個類別,如果需要呼叫父類別建構式,則只有主要建構式能夠呼叫,輔助建構式是不能呼叫父類別建構式的。由於 bal 在父類別中是宣告為 protected,所以可以(也僅能)在子類別中使用(跟 Java 不同的是,Scala 的 protected 並沒有 package-private 的含義)。如果在子類別中,打算呼叫父類別的方法,則可以如範例中,使用 super 來呼叫. 上例中,由於 id 與 name 的定義,與父類別是一致的,所以必須使用 override 指明,你要定義的成員確實是與父類別相同的,如果你不使用override, 則編譯器也會提醒你,你正試圖定義父類別已有的成員 : 


如果你在定義類別時,加上 fina l關鍵字,則該類別將不再能被繼承,例如 : 
  1. final class SuperAccount  {} // 這個類別不能被繼承  
如果在類別中定義方法時,加上 fina 關鍵字,則子類別不可以重新定義該方法 : 
  1. class FakeAccount {  
  2.     final def withdraw(amount: Int) = 0 // 不能被重新定義  
  3. }  
Supplement 
Tutorialspoint - Scala - Classes & Objects

沒有留言:

張貼留言

網誌存檔

關於我自己

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