Scala的類繼承
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 }
類裝載機制執行大致如下
- Ant的構造器初始化之前,呼叫Animal的構造器
- Animal的構造器將age設定為10
- Animal的構造器初始化array陣列,呼叫age()取值器
- 輸出Ant類的range欄位值
- range方法返回0(預設值為0)
- env被設為長度為0的陣列
-
Ant的構造器繼續執行,將其range欄位設為2
從程式碼看range可能為10或者為2,但是env被設為長度為0的陣列,因為欄位預設都有get/set方法,Ant類繼承了env,由於env沒有重寫,預設構造為長度為0的陣列
解決衝突有以下方法:
1. 將val宣告為final 2. 在超類中val宣告為lazy 3. 在子類總使用提前定義語法如下: classAnt 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方法