Golang中介面定義及實現,空介面,介面巢狀學習
在Golang中,介面是一組方法簽名。當型別為介面中的所有方法提供定義時,它被稱為實現介面。它與OOP(物件導向程式設計)
非常相似。介面指定了型別應該具有的方法,型別決定了如何實現這些方法。
如果某個物件實現了某個介面的所有方法,則此物件就實現了該介面。
1.定義介面
關鍵字interface
用來定義介面,語法如下:
type interface_name interface {
method_name1([args ...arg_type]) [return_type]
method_name2([args ...arg_type]) [return_type]
method_name3([args ...arg_type]) [return_type]
...
method_namen([args ...arg_type]) [return_type]
}
一個介面中可以定義多個方法,根據邏輯需要,自定義引數和返回值。
2.實現介面
一個結構體實現了某個介面的所有方法,則此結構體就實現了該介面。
我們定義一個Phone
介面,包含兩個方法call()
和sendMessage()
type Phone interface {
call()
seenMessage()
}
宣告結構體,用來實現介面:
type Huawei struct {
name string
price float64
}
type Xiaomi struct {
name string
price float64
}
宣告瞭Huawei
和Xiaomi
兩個結構體,各包含name
和price
兩個欄位。
接下來,實現Phone
介面,我們先讓Huawei
結構體實現該介面所有方法:
func (huawei Huawei) call() {
fmt.Printf("%s 有打電話功能.....\n", huawei.name)
}
func (huawei Huawei) seenMessage() {
fmt.Printf("%s 有發簡訊功能.....\n", huawei.name)
}
初始化Huawei
結構體,測試介面的方法:
mate30 := Huawei{
name: "Mate 30",
price: 6999,
}
mate30.call()
mate30.seenMessage()
輸出:
Mate 30 有打電話功能.....
Mate 30 有發簡訊功能.....
Huawei
結構體實現了Phone
介面的所有方法,那就認為,則Huawei
結構體實現了Phone
介面。
那如何判斷是否實現了該介面,可參考:
Golang學習——如何判斷Golang介面是否實現?
我們具體也操作下,看看Xiaomi
結構體若沒有實現Phone
介面會發生什麼?
實現Phone
介面一個方法:
func (xiaomi Xiaomi) seenMessage() {
fmt.Printf("%s 只有發簡訊功能.....\n", xiaomi.name)
}
Xiaomi
只實現了 Phone
的 發簡訊方法,所以認為 Xiaomi
型別未實現了 Phone
介面。我們具體驗證下:
首先初始化Xiaomi
結構體,並測試方法
xiaomi9 := Xiaomi{
name: "Xiao 9",
price: 4999,
}
xiaomi9.seenMessage()
輸出:
Xiao 9 只有發簡訊功能.....
seenMessage()
方法測試沒問題,我們使用new()
函式來測試下Xiaomi
結構體是否實現了Phone
介面:
var _ Phone = new(Xiaomi)
下圖是我從自己的IDE(Goland)截的圖,為了方便記錄,我將上下文的程式碼專門換行隔開了。
從圖中可以看到,new
下方有紅線,滑鼠浮上去會顯示錯誤資訊,大意就是:Xiaomi
未實現Phone
介面的某些方法,如:call()
,因此不能將Xiaomi
用作電話型別。
空介面 interface{}
:
不包含任何的方法,正因為如此,所有的型別都實現了空介面,因此空介面可以儲存任意型別的數值。
fmt
包下的Print
系列函式,其引數大多是空介面型別,也可以說支援任意型別:
func Print(a ...interface{}) (n int, err error)
func Println(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
1.例項
我們定義一個空介面練習下:
// 定義一個空介面
type Empyt_interface interface {
}
// 定義一個入參為任意型別的函式
func getInfo(arg Empyt_interface) {
fmt.Println("getInfo 函式.....", arg)
}
// 也可以寫成如下形式,更推薦
func getInfo2(arg interface{}) {
fmt.Println("getInfo2 函式.....", arg)
}
Golang
很多庫的原始碼都會以空介面作為引數,表示接受任意型別的引數
我們自己也實戰一下:
定義一個值為任意型別的 map
map1 := make(map[string] interface{})
map1["數字"] = 1
map1["字串"] = "字串"
map1["布林"] = false
fmt.Println("map1 ...........", map1)
輸出:
map1 ........... map[字串:字串 布林:false 數字:1]
顧名思義,介面巢狀就是一個介面中包含了其他介面,如果要實現外部介面,那麼就要把內部巢狀的介面對應的所有方法全實現了。
1.例項
我們定義3個介面,其中有一個介面巢狀了另外兩個:
// 定義3個介面
type A interface {
test1()
}
type B interface {
test2()
}
// 定義巢狀介面
type C interface {
A
B
test3()
}
接著我們在定義一個結構體,並實現所有方法:
type Person struct {
//如果想實現介面C,那不止要實現介面C的方法,還要實現介面A,B中的方法
}
func (p Person) test1() {
fmt.Println("test1 方法................")
}
func (p Person) test2() {
fmt.Println("test2 方法................")
}
func (p Person) test3() {
fmt.Println("test3 方法................")
}
初始化結構體,並測試方法:
var person Person = Person{}
// 實現 C 介面的所有方法
person.test1()
person.test2()
person.test3()
輸出:
test1 方法................
test2 方法................
test3 方法................
以上就是Golang介面的基礎學習,總結了介面的定義及實現,空介面和巢狀介面的概念和使用。
本作品採用《CC 協議》,轉載必須註明作者和本文連結