最近扣丁學堂上線區塊鏈培訓課程,包括從入門到精通、GO語言等課程內容,有很多學員反映出一個問題對於Interface介面的使用不知道怎麼解決,老師根據學員的需求編寫成了一篇文章,現在分享給大家,下面我們一起來看一下吧。
介面是一個或多個方法簽名名的集合,定義方式如下
typeInterface_Nameinterface{method_a()stringmethod_b()int....}
只要某個類型擁有該介面的所有方法簽名,就算實現該介面,無需顯示聲明實現了那個介面,這稱為structuralTyping
packagemain
import"fmt"
typeUSBinterface{//定義一個介面:方法的集合
Name()string//Name方法,返回string
Connect()//Connect方法
}
typePhoneConnecterstruct{//定義一個結構
namestring//結構包含一個欄位
}
func(pcPhoneConnecter)Name()string{//為結構定義一個方法,綁定介面
returnpc.name//該方法命名為介面內的欄位
}//返回結構體欄位
func(pcPhoneConnecter)Connect(){//定義結構體另一個方法,與介面另一個方法綁定
fmt.Println("Connect:",pc.name)
}
funcmain(){
varaUSB//定義一個變數為USB介面類型
a=PhoneConnecter{"PhoneConnecter"}//執行個體化一個結構體,並賦值給變數(介面)USB
a.Connect()//介面調用其Connect方法,也是結構方法
}
/*輸出
Connect:PhoneConnecter
*/
介面可以作為匿名嵌入其它介面,或嵌入到結構中
packagemain
import"fmt"
typeUSBinterface{//定義一個介面:方法的集合
Name()string//Name方法,返回string
Connecter//嵌入Connecter介面,可以使用Connecter方法
}
typeConnecterinterface{//定義另一個介面Connecter
Connect()//包含一個介面方法:Connect
}
typePhoneConnecterstruct{//定義一個結構
namestring//結構包含一個欄位
}
func(pcPhoneConnecter)Name()string{//為結構定義一個方法,綁定介面
returnpc.name//該方法命名為介面內的欄位
}//返回結構體欄位
func(pcPhoneConnecter)Connect(){//定義結構體另一個方法,與介面另一個方法綁定
fmt.Println("Connect:",pc.name)
}
funcmain(){
varaUSB//定義一個變數為USB介面類型
a=PhoneConnecter{"PhoneConnecter"}//執行個體化一個結構體,並賦值給變數(介面)USB
a.Connect()
Disconnect(a)//介面調用其Connect方法,也是結構方法
}
介面只是方法聲明,沒有實現調用,沒有欄位,只能通過綁定的類型方法訪問
packagemain
import"fmt"
typeUSBinterface{//定義一個介面:方法的集合
Name()string//Name方法,返回string
Connecter//嵌入Connecter介面,可以使用Connecter方法
}
typeConnecterinterface{//定義另一個介面Connecter
Connect()//包含一個介面方法:Connect
}
typePhoneConnecterstruct{//定義一個結構
namestring//結構包含一個欄位
}
func(pcPhoneConnecter)Name()string{//為結構定義一個方法,綁定介面
returnpc.name//該方法命名為介面內的欄位
}//返回結構體欄位
func(pcPhoneConnecter)Connect(){//定義結構體另一個方法,與介面另一個方法綁定
fmt.Println("Connected:",pc.name)
}
funcmain(){
varaUSB//定義一個變數為USB介面類型
a=PhoneConnecter{"htcM10"}//執行個體化一個結構體,並賦值給變數(介面)USB
a.Connect()
Disconnect(a)//介面調用其Connect方法,也是結構方法
}
funcDisconnect(usbUSB){
ifpc,ok:=usb.(PhoneConnecter);ok{//傳入結構體,判斷賦值是否成功
fmt.Println("Disconnected:",pc.name)
return
}
fmt.Println("UNknowndevice.")
}
/*輸出
Connect:htcM10
Disconnect:htcM10
*/
go沒有像其他語言繼承,如python中的object表示元類,所有的類都繼承自object類,go通過介面也類似實現了此定義,因為只要某個類型實現了某個介面的方法,我們就說此類實現了這個介面。因為typeemptyinterface{}---空介面沒有任何方法,所以可以理解為所有的介面都實現了空介面的方法(繼承)。
packagemain
import"fmt"
typeUSBinterface{//定義一個介面:方法的集合
Name()string//Name方法,返回string
Connecter//嵌入Connecter介面,可以使用Connecter方法
}
typeConnecterinterface{//定義另一個介面Connecter
Connect()//包含一個介面方法:Connect
}
typePhoneConnecterstruct{//定義一個結構
namestring//結構包含一個欄位
}
func(pcPhoneConnecter)Name()string{//為結構定義一個方法,綁定介面
returnpc.name//該方法命名為介面內的欄位
}//返回結構體欄位
func(pcPhoneConnecter)Connect(){//定義結構體另一個方法,與介面另一個方法綁定
fmt.Println("Connected:",pc.name)
}
funcmain(){
varaUSB//定義一個變數為USB介面類型
a=PhoneConnecter{"htcM10"}//執行個體化一個結構體,並賦值給變數(介面)USB
a.Connect()
Disconnect(a)//介面調用其Connect方法,也是結構方法
}
#funcDisconnect(usbinterface{}){//整合空介面,也可以實現
#ifpc,ok:=usb.(PhoneConnecter);ok{//傳入結構體,判斷賦值是否成功
#fmt.Println("Disconnected:",pc.name)
#return
#}
#fmt.Println("UNknowndevice.")
#}
//通過switch判斷介面類型:type...switch用法
funcDisconnect(usbinterface{}){//整合空介面,也可以實現
switchv:=usb.(type){
casePhoneConnecter:
fmt.Println("Disconnected:",v.name)
default:
fmt.Println("UNknowndevice.")
}
}
/*輸出
Connect:htcM10
Disconnect:htcM10
*/
介面間的轉換:只有子類介面可以轉換為父類介面,因為父類介面包含了子類介面,子類介面可以調用父類介面一部分介面方法
將對象賦值給介面是,會發生拷貝,而介面內部儲存的是只想這個複製品的指標,也就意味著介面無法修改狀態,也無法擷取指標。
...
funcmain(){
pc:=PhoneConnecter{"ipadbookpro"}//執行個體化一個結構
varaConnecter//定義a為介面變數
a=Connecter(pc)//介面強制轉換
a.Connect()
pc.name="Iphone7"
a.Connect()
...
/*輸出
pc.name="ipadbookpro"Connected:ipadbookpro
pc.name="Iphone7"Connected:ipadbookpro
*/
}
只有當介面儲存的類型和對象都為nil時,介面才等於nil
packagemain
import"fmt"
funcmain(){
varainterface{}
fmt.Println(a==nil)
varp*int=nil
a=p
fmt.Println(a==nil)
}
/*輸出
true
false
*/
介面調用不會做Receiver的自動轉換
介面同樣支援匿名欄位的方法
介面也可以實作類別似OOP(物件導向編程)中的多態
空介面可以作為任何類型資料的容器
以上就是本文的全部內容,希望對大家的學習有所協助。