物件導向程式設計 - 繼承
復用 ~ 可擴充套件性 ~ 可維護性
extends
使用 extends 關鍵字表示繼承。
繼承就代表,子類可以從父類繼承父類的 field 和 method 。子類可以在自己內部放入父類所沒有的子類特有的 field 和 method 。
使用繼承可以有效復用**。
子類可以覆蓋父類的 field 和 method 。
如果父類用 final 修飾, field 和 method 用 final 修飾,則該類無法被繼承的, field 和 method 是無法被覆蓋的。
override 和 super
在 scala 中,如果子類要覆蓋乙個父類中非抽象方法,則必須使用 override 關鍵字。
override 關鍵字可以幫助我們盡早地發現**裡的錯誤。
在子類覆蓋父類方法之後,想要呼叫父類中被覆蓋的方法則用 super 關鍵字。
class person
class student extends person
override field
子類可以覆蓋父類的 val field ,而且子類的 val field 還可以覆蓋父類的 val field 的 getter 方法。使用 override 關鍵子。
class person
class student extends person
isinstanceof 和 asinstanceof
如果我們建立了子類的物件,但是又將其賦予了父類型別的變數。在後續的程式中,又需要將父類型別的變數轉換為子類型別的變數,如何改變?
首先,需要使用 ininstanceof 判斷物件是否是指定類的物件,如果是的話,則可以使用 asinstanceof 將物件轉換為指定型別。
**注意:**如果物件是 null ,則 isinstanceof 一定返回 false ,asinstanceof 一定返回 null 。
**注意:**如果沒有用 isinstanceof 先判斷物件是否為指定類的例項,就直接用 asinstanceof 轉換,則可能會丟擲異常。
父類轉變成子類,用 isinstaceof
和 asinstanceof 。
class person
class student extends person
val p:person = new student
var s:student = null
if(p.isinstaceof[student])s=p.asinstanceof[student]
getclass 和 classof
isinstanceof 只能判斷出物件是否是指定類以及其之類的物件,不能精確判斷出物件就是指定類的物件。
如果要求精確地判斷物件就是指定類的物件,那就只能使用 getclass 和
classof 了。
物件 .getclass 可以精確獲取物件的類, classof[類] 可以精確獲取類,使用 == 操作符即可判斷。
class person
class student extends person
val p:person = new student
p.isinstanceof[person]
p.getclass
// p.getclass 的返回: class[_ <: person] = class student
p.getclass == classof[person]
// 返回為 flase
p.getclass == classof[student]
// 返回為 true
使用模式匹配進行型別判斷
實際開發中,很多地方都使用模式匹配的方式來進行型別的判斷,這種方式更加簡潔明瞭,而且**的可維護性和可擴充套件性也非常高。
使用模式匹配,功能性上來說,與 isinstanceof 一樣,也是判斷主要是該類以及該類的子類的物件,不是精準判斷。
class person
class student extends person
val p:person = new student
p match
protected
scala 中同樣可以使用 protected 關鍵字來修飾 field 和 method ,這樣在子類中就不需要 super 關鍵字,直接就可以訪問 field 和 method 。
還可以使用 protected[this],這樣只能在當前子類物件中訪問父類的 field 和 method ,無法通過其他子類物件訪問父類的 field 和 method 。
// example1
class person
class student extends person
}val s1 = new student
val s2 = new student
s1.makefriends(s2)
// 這裡輸出為:
// hi,my name is li,your name is li
// 所以這裡不僅可以通過繼承來訪問父類的 field ,還可以通過其他例項來訪問。
// example2
// 會報錯
class person
class student extends person
}
以上定義會報錯:
:18: error: value name is not a member of student
println("hi, my name is" + name + ", your name is " + s.name)
呼叫父類的 constructor
在 scala 中,每個類可以有乙個主 constructor 和任意多個輔助 constructor,而每個輔助 constructor 的第一行都必須是呼叫其他輔助 constructor 或者是主 constructor,因此子類的輔助 constructor 是一定不可能直接呼叫父類的 constructor 的。
只能在子類的主 constructor 中呼叫父類的 constructor 。
如果是父類中接收的引數,比如 name 和 age,子類中接受時,就不要用任何 val 或者 var 來修飾了,否則認為是子類要覆蓋父類的 field 。
class person(val name:string, val age:int)
// 這裡的 name 和 age 就是使用的父類的。
class student (name:string,age:int,var score:double) extends person(name,age)
def this(age:int)
}val s = new student("li",20,100)
匿名內部類
定義乙個類的沒有名稱的子類,並直接建立其物件,然後將物件的引用賦予乙個變數。還可以將該匿名子類的物件傳遞給其他函式。
class person(val name:string)
// 以下就是匿名內部類
val p = new person("li")
def greeting(p: person)
抽象類
如果在父類中的一些方法無法立即實現,需要依賴不同的子類來覆蓋,重寫實現自己不同的方法來實現,此時可以將父類中的這些方法不給出具體的實現,只有方法簽名,這種方法就是抽象方法。
在類中如果有乙個抽象方法,那麼類就必須用abstract 來宣告為抽象類,此時抽象類是不可以例項化的。
在子類中覆蓋抽象類的抽象方法時,不需要使用 override 關鍵字。
abstract class person(val name:string)
class student(name:string)extends person(name)
抽象 field
如果在父類中,定義了 field ,但是沒有給出初始值,則此 field 為抽閒 field 。
抽象 field 意味著,scala 會根據自己的規則,為 var 或 val 型別的 field 生成對應的 getter 和 setter 方法,但是父類中是沒有該 field 的。
子類必須覆蓋 field 來定義自己具體的 field ,並且覆蓋抽象 field ,不需要使用 override 關鍵字。
abstract class person
class student extends person
SCALA物件導向程式設計(二)
五 隱式轉換和隱式函式 5.1隱式轉換 implicit def a d double d.toint 先宣告隱式函式,宣告後就不用管,程式過不去,會自動查詢。val i1 int 3.5 ok 當發現程式有誤時,scala編譯器會嘗試在隱式函式列表中查詢可以進行轉換的函式 注意 5.2利用隱式轉換...
scala的物件導向程式設計
一 簡單的程式設計 1.scala的簡單程式設計 1 packageer2 3class people 9 def watchfootball teamname string string 12 13object two 22 2.效果 3.構造方法 主構造方法,輔助構造方法。輔助建構函式是在主建構...
物件導向程式設計 繼承
繼承是物件導向程式設計的主要特點之一。繼承,顧名思義就是子繼承父的所有。在面向程式設計中繼承的意思並沒變,子類繼承父類所擁有的屬性 方法。使用extends關鍵字使子類繼承父類,子類就可以自動復用父類的方法了 私有方法除外 並且繼承了父類的所有屬性。在子類例項化過程中子類的構造方法一定會去呼叫父類的...