1. 程式人生 > >Scala的類繼承

Scala的類繼承

調用 代碼片段 tro tostring 聲明 輸出 animal () 默認

Scala的類繼承

  • extend

    Scala擴展類的方式和java一樣使用extends關鍵字
    class Employee extends Person {

}

與java一樣,可以在定義的子類重寫超類的方法,定義父類不存在的屬性和方法

  • override
class Person {
    override def toString = getClass.getName +"name="
}

在Scala中調用的超類的方法和java完全一致,使用super關鍵字

public class Employee extends Person {
     override def toString = super.toString
}
  • 類型檢查和轉換

    測試某個對象是否某個給定的類,可以使用isInstanceOf方法,如果返回true,可以使用asInstanceOf方法將引用轉為子類的引用,現在看下面的代碼:

   if(p.isInstanceOf[Employee]) {
        // s的類型為Employee
       val s = p.asInstanceOf[Employee]
   }

分析上面的代碼片段,若p指向的是Employee類及其子類(假定子類是Manager),則p.isInstanceOf[Employee] 返回true,否則返回false,另外還有一種情況是:p指向是一個Employee對象而不是其子類,可以使用 if(p.getClass == classOf[Employee])

  • 保護字段

    與java一致,可以將字段或方法聲明為protected,這樣的成員可以被任何子類訪問,但其他位置無法訪問。Scala中提供了protected[this] 將訪問權限限定在當前的對象

  • 構造的執行優先級

    當你在子類重寫val並且在超類的構造器中使該值的話,不一定可以看到重寫的val變量。以下面例子說明

父類:
class Animal {
    val age : Int = 10
    val array : Array[Int] = new Array[Int](age)
}

子類:
class Ant extends Animal {
    override val age = 2
}

類裝載機制運行大致如下

  1. Ant的構造器初始化之前,調用Animal的構造器
  2. Animal的構造器將age設置為10
  3. Animal的構造器初始化array數組,調用age()取值器
  4. 輸出Ant類的range字段值
  5. range方法返回0(默認值為0)
  6. env被設為長度為0的數組
  7. Ant的構造器繼續執行,將其range字段設為2

    從代碼看range可能為10或者為2,但是env被設為長度為0的數組,因為字段默認都有get/set方法,Ant類繼承了env,由於env沒有重寫,默認構造為長度為0的數組
    解決沖突有以下方法:

1. 將val聲明為final
2. 在超類中val聲明為lazy
3. 在子類總使用提前定義語法如下:
class  Ant extends{ override val range = 2}with Animal
  • 對象相等性

    當定義產品Item可能會認為兩個物件有相同的描述和價格就是相等的,應該是以下equals方法

final override def equals(other: Any) = {
    val that = other.asInstanceOf[Item]
    if(that==null) false else description ==that.description && price ==that.price
}
註意要確保equals的方法參數類型為Any,否則不會重寫equals方法

Scala的類繼承