Scala 8 物件導向程式設計 繼承

2021-10-02 23:04:10 字數 4354 閱讀 3666

物件導向程式設計 - 繼承

復用 ~ 可擴充套件性 ~ 可維護性

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關鍵字使子類繼承父類,子類就可以自動復用父類的方法了 私有方法除外 並且繼承了父類的所有屬性。在子類例項化過程中子類的構造方法一定會去呼叫父類的...