Golang interface

接口在Golang中表示一種抽象的數(shù)據(jù)類(lèi)型,它用來(lái)定義對(duì)象的行為,具體的實(shí)現(xiàn)由對(duì)象決定。程序編寫(xiě)時(shí)如果僅僅定義接口是沒(méi)有實(shí)際意義的,我們需要自定義類(lèi)型,如果類(lèi)型對(duì)某個(gè)接口的所有方法提供了定義,就說(shuō)這個(gè)類(lèi)型實(shí)現(xiàn)了該接口。

  • 定義接口
    Golang中接口的定義使用interface關(guān)鍵字,后面緊跟一個(gè)大括號(hào),里面包含若干函數(shù)(參數(shù)和返回值不是必需的),比如,
type People interface {
    GetName() string                // 帶有返回值的方法
    GetAge(id int)                     // 帶有參數(shù)的方法
    GetTelephone(a int) int      //同時(shí)帶有參數(shù)和返回值的方法
}

一個(gè)接口是方法集的藍(lán)圖,在使用前必須有類(lèi)型實(shí)現(xiàn)它,如果不能滿(mǎn)足這個(gè)條件,接口是不能使用的。

  • 定義一個(gè)實(shí)現(xiàn)接口的類(lèi)型
    下面定義一個(gè)帶有兩個(gè)方法的接口:People,然后定義一個(gè)類(lèi)型:Ple,該類(lèi)型擁有People中聲明的方法(注意:這里方法的參數(shù)和返回值都要和接口People中的方法保持一致)
package main

import "fmt"

type People interface {
    GetName(name string)
    GetAge(a int) int
}

type Ple struct {
}

func (p Ple) GetName(name string) {
    fmt.Println("People Name:\t", name)
}

func (p Ple) GetAge(a int) int {
    return a
}

func main() {
    var p1 People
    p1 = Ple{}
    p1.GetName("John Doe")
    fmt.Println("Ple Age:", p1.GetAge(25))
}

上面代碼中Ple類(lèi)型實(shí)現(xiàn)了接口People聲明的所有方法,此時(shí),就可以將Ple的實(shí)例賦值給People的變量p1。

  • 定義滿(mǎn)足多個(gè)接口的類(lèi)型
    用戶(hù)自定義類(lèi)型可以同時(shí)滿(mǎn)足多個(gè)接口,使用“類(lèi)型斷言”(即Type Assertion)可以得到實(shí)際的自定義類(lèi)型,通過(guò)該類(lèi)型調(diào)用接口未包含的方法:
package main

import "fmt"

type People interface {
    GetName()
}

type Animal interface {
    GetAge()
}

type Custom struct 
}

func (c Custom) GetName() {
    fmt.Println("name is xiaoli")
}

func (c Custom) GetAge() {
    fmt.Println("age is 5")
}

func main() {
    var p People = Custom{}
    p.GetName()
    p.GetAge()
    var o Custom = p.(Custom)
    o.GetAge()
}

將“Custom”類(lèi)型的實(shí)例賦值給接口變量p,可以直接通過(guò)接口變量p調(diào)用方法“GetName”,但是不能直接調(diào)用方法“GetAge”,因?yàn)榻涌凇癙eople”沒(méi)有方法“GetAge”,這時(shí)使用類(lèi)型斷言得到實(shí)際的自定義類(lèi)型值,就可以調(diào)用接口“People”本不具有的方法“GetAge”。(上面代碼的最后兩行可以直接寫(xiě)成“p.(Custom).GetAge()”)

  • 接口接收變量的地址
package main
 
 import "fmt"
 
 type Student struct {
     name,address string
 }
 
 func (s *Student) Init (n,d string) {
     s.name = n
     s.address = d
 }
 
 func (s *Student) Print () {
     fmt.Printf("Student name is %s,address is %s \n",s.name,s.address)
 }
 
 type Printer interface {
     Print()
 }
 
 func main() {
     var s Student
     s.Init("xiaoli","shenzhen")
     var p Printer
     p = &s  //賦值地址類(lèi)型
     p.Print()
 }

因?yàn)镻rinter方法有指針接收者:“func (s *Student) Print ()”,所以給接口變量賦值時(shí),必須使用變量地址:“p = &s”,如果不符合,會(huì)有如下報(bào)錯(cuò):

# command-line-arguments
./interface-test.go:26:4: cannot use s (type Student) as type Printer in assignment:
    Student does not implement Printer (Print method has pointer receiver)
  • 空接口類(lèi)型
    類(lèi)型“interface{}”稱(chēng)之為空接口,因?yàn)榭战涌陬?lèi)型沒(méi)有定義任何方法,所以任何類(lèi)型都可以認(rèn)為實(shí)現(xiàn)了該接口,當(dāng)一個(gè)函數(shù)不在乎參數(shù)類(lèi)型時(shí),可以指定參數(shù)類(lèi)型為“interface{}”
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容