Golang的面向接口編程
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
之前我們分享了Go語言中的面向對象的封裝和繼承相關知識,今天我們來了解一下Go語言如何實現多態。
一.接口概述
Go語言的接口類型用於定義一組行為,其中每個行為都由一個方法聲明表示。
接口類型中的方法聲明只有方法簽名而沒有方法體,而方法簽名包括且僅包括方法的名稱,參數列表和結果返回列表。
在Go語言中,接口是一個自定義類型,它聲明了一個或者多個方法簽名。接口是完全抽象的,因此不能將其實例化。然而,可以創建一個其類型為接口的變量,它可以被賦值為任何滿足該接口類型的實際類型的值。
二.計算器案例(多態案例)
package main import ( "fmt" ) //實現面向對象版本包含加減法的計算器 type Parents struct { x int y int } //實現加法類 type Addition struct { Parents } //實現減法類 type Subtraction struct { Parents } //實現乘法類 type multiplication struct { Parents } //實現除法類 type Division struct { Parents } func (this *Addition) Operation() int { return this.x + this.y } func (this *Subtraction) Operation() int { return this.x - this.y } func (this *multiplication) Operation() int { return this.x * this.y } func (this *Division) Operation() int { return this.x / this.y } /** 實現接口版本包含加減法的計算器 接口就是一種規范標准,接口中不做函數實現,只做定義函數格式 面向接口編程(也稱為面向協議編程)降低了代碼的耦合度,方便后期代碼的維護和擴充,這種實現方法我們稱之為多態。 多態三要素: 1>.父類是接口; 2>.子類實現所有的接口中定義的函數; 3>.有一個父類接口對應子類對象指針; */ type MyCalculator interface { Operation() int //實現接口的結構體中必須包含Operation函數名且返回值為int類型 } func Calculation(c MyCalculator) int { return c.Operation() } func main() { //調用加法 a := Addition{Parents{100, 20}} sum := a.Operation() fmt.Println(sum) //調用減法 b := Subtraction{Parents{100, 20}} sub := b.Operation() fmt.Println(sub) //調用乘法 c := multiplication{Parents{100, 20}} mul := c.Operation() fmt.Println(mul) //調用除法 d := Division{Parents{100, 20}} div := d.Operation() fmt.Println(div) fmt.Println("===== 我是分割線 =====") //調用接口,需要傳入對象指針,相比上面面向對象的方法來說,接口表現了面向接口三要素中的多態特征。 fmt.Println(Calculation(&a)) fmt.Println(Calculation(&b)) fmt.Println(Calculation(&c)) fmt.Println(Calculation(&d)) }
三.空接口和類型斷言案例
package main import ( "fmt" "reflect" ) /** 空接口(interface{})不包含任何的方法,正因為如此,所有的類型都實現了空接口,因此空接口可以存儲任意類型的數值。 如下所示,我們為空接口起了一個別名. */ type MyInterface interface{} func MyPrint(input MyInterface) { /** 使用斷言語法獲取傳輸過來的數據類型,類似於類型強轉。 斷言語法格式如下: 接口類型變量.(斷言的類型) 如果你不確定interface具體是什么類型,那么再斷言之前最好先做判斷。 */ output, ok := input.(int) if ok { output = input.(int) + 100 //通過斷言語法可以判斷數據類型 fmt.Println(output) } else { fmt.Println(input) } inputType := reflect.TypeOf(input) //通過反射也可以判斷類型 fmt.Printf("用戶傳入的是:[%v],其對應的類型是[%v]\n\n", input, inputType) } func main() { m1 := true MyPrint(m1) m2 := "Jason Yin" MyPrint(m2) m3 := 2020 MyPrint(m3) }