新聞中心
前言
并且接口在代碼中用的還是比較多的,一起來(lái)看看吧!

十余年的太湖網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整太湖建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“太湖網(wǎng)站設(shè)計(jì)”,“太湖網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
什么是接口(interface)
這里的接口,可不是說(shuō)那種插槽的那種接口,互相懟到一塊就完事了。
在各種語(yǔ)言中,提到接口,通常指的之一種規(guī)范,然后具體對(duì)象來(lái)實(shí)現(xiàn)這個(gè)規(guī)范的細(xì)節(jié)。
本文使用的接口主要是約束接口,還有一種存儲(chǔ)接口。
注:
在Go中,接口(interface)是一種類(lèi)型,一種抽象類(lèi)型,它只有方法,沒(méi)有屬性。
為什么需要接口
我們?cè)谥v結(jié)構(gòu)體時(shí),Go語(yǔ)言基礎(chǔ)之結(jié)構(gòu)體(春日篇)、Go語(yǔ)言基礎(chǔ)之結(jié)構(gòu)體(夏日篇)、Go語(yǔ)言基礎(chǔ)之結(jié)構(gòu)體(秋日篇),提到過(guò)繼承這個(gè)概念,Go是通過(guò)結(jié)構(gòu)體來(lái)完成繼承的。
回顧繼承
車(chē)結(jié)構(gòu)體
//車(chē)
type Car struct {
Brand string //車(chē)品牌
CarNum string //車(chē)牌號(hào)
Tyre int //輪胎個(gè)數(shù)
}
//給車(chē)綁定一個(gè)方法,說(shuō)明車(chē)的基本信息
func (this *Car) carInfo() {
fmt.Printf("品牌:%s,車(chē)牌號(hào):%s,輪胎個(gè)數(shù):%d\n", this.Brand, this.CarNum, this.Tyre)
}
車(chē)結(jié)構(gòu)體有四個(gè)屬性,同時(shí)還有一個(gè)顯示車(chē)(carInfo)信息的方法。
寶馬車(chē)
//寶馬車(chē)
type BMWCar struct {
//*Car和Car基本沒(méi)有區(qū)別,一個(gè)存的是整個(gè)結(jié)構(gòu)體,一個(gè)存的是結(jié)構(gòu)體地址,用法大同小異
*Car //這就表示繼承了Car這個(gè)結(jié)構(gòu)體
}
比亞迪車(chē)
//比亞迪車(chē)
type BYDCar struct {
*Car
}
main代碼
func main() {
//一個(gè)寶馬對(duì)象
var bmw1 = BMWCar{&Car{
Brand: "寶馬x8",
CarNum: "京666",
Tyre: 4,
}
}
//一個(gè)比亞迪對(duì)象
var byd1 = BYDCar{&Car{
Brand: "比亞迪L3",
CarNum: "京111",
Tyre: 4,
}
}
//因?yàn)?BMWCar 和 BYDCar 都繼承了Car,所以都有carInfo這個(gè)方法
bmw1.carInfo()
byd1.carInfo()
}
執(zhí)行結(jié)果
通過(guò)回顧,我們可以發(fā)現(xiàn),車(chē),應(yīng)該作為一個(gè)基本的概念。
上述Car結(jié)構(gòu)體似乎顯示了車(chē)的屬性,其實(shí)是不太對(duì)的。
車(chē)就是一個(gè)抽象的概念,電瓶車(chē)是車(chē),小轎車(chē)也是車(chē),大卡車(chē)也是車(chē)。
這些車(chē)至少有一個(gè)統(tǒng)一的功能,那就是跑,但是像幾個(gè)輪胎了,什么品牌了。
應(yīng)該是屬于自己的,不再是屬于Car這個(gè)抽象的概念中了,所以,這時(shí)候用接口會(huì)更好。
定義接口
車(chē)接口
type Car interface {
//車(chē)會(huì)跑
Run(speed int)
//車(chē)需要加油
Refuel(oil int)
//車(chē)需要轉(zhuǎn)彎
Wheel(direction string)
}
假設(shè)車(chē),至少有這三個(gè)動(dòng)作,不管任何結(jié)構(gòu)體,只要實(shí)現(xiàn)了Car里面的所有方法,就代表它一定是一個(gè)車(chē)。
寶馬車(chē)
//寶馬車(chē)
type BMWCar struct {
Owner string //車(chē)主
Brand string //車(chē)品牌
CarNum string //車(chē)牌號(hào)
}
//構(gòu)造方法
func NewBMWCar(owner string, brand string, carNum string) *BMWCar {
return &BMWCar{Owner: owner, Brand: brand, CarNum: carNum}
}
func (this *BMWCar) Run(speed int) {
fmt.Printf("我是 %s,我的車(chē)是 %s,我車(chē)牌號(hào)為 %s,我正在以 %d 速度行駛\n", this.Owner, this.Brand, this.CarNum, speed)
}
func (this *BMWCar) Refuel(oil int) {
fmt.Printf("老板,加%d升油\n", oil)
}
func (this *BMWCar) Wheel(direction string) {
fmt.Printf("我正在%s轉(zhuǎn)彎\n", direction)
}
電瓶車(chē)
//電瓶車(chē)
type Electromobile struct {
Owner string //車(chē)主
Brand string //車(chē)品牌
}
func NewElectromobile(owner string, brand string) *Electromobile {
return &Electromobile{Owner: owner, Brand: brand}
}
func (this *Electromobile) Run(speed int) {
fmt.Printf("我是 %s,我的車(chē)是 %s,我正在以 %d 速度行駛\n", this.Owner, this.Brand,, speed)
}
func (this *Electromobile) Refuel(oil int) {
fmt.Printf("你妹的,你電動(dòng)車(chē)加啥油...\n")
}
func (this *Electromobile) Wheel(direction string) {
fmt.Printf("我正在%s轉(zhuǎn)彎\n", direction)
}
這里是有區(qū)別的,電瓶車(chē)沒(méi)有屬性CarNum,但是仍然實(shí)現(xiàn)了Car接口的所有方法,所以電瓶車(chē)在代碼上,仍然是車(chē)。
main
func main() {
var 張三的車(chē) Car
張三的車(chē) = NewBMWCar("張三", "寶馬6", "京666")
張三的車(chē).Run(80)
張三的車(chē).Refuel(20)
張三的車(chē).Wheel("左")
var 李四的車(chē) Car
李四的車(chē) = NewElectromobile("李四", "小刀電動(dòng)車(chē)")
李四的車(chē).Run(40)
李四的車(chē).Refuel(0)
李四的車(chē).Wheel("左")
}
第2行代碼和第8行代碼,變量類(lèi)型是Car接口類(lèi)型,但是在賦值時(shí),確是其他類(lèi)型。
Go是強(qiáng)類(lèi)型語(yǔ)言,為什么類(lèi)型不一致,還可以賦值,那執(zhí)行結(jié)果會(huì)出問(wèn)題嗎???
執(zhí)行結(jié)果
但是我們發(fā)現(xiàn)執(zhí)行結(jié)果是沒(méi)問(wèn)題的。
但是為啥變量類(lèi)型不一致,還是可以進(jìn)行賦值并且每報(bào)錯(cuò)呢?
我們上述代碼可以確定寶馬車(chē)和電瓶車(chē)完全實(shí)現(xiàn)了Car接口里面所有的方法。
所以可以理解為Car就是他們的爸爸,用他們的爸爸來(lái)接收兒子,當(dāng)然可以咯。
一個(gè)結(jié)構(gòu)體實(shí)現(xiàn)多個(gè)接口
以下代碼沒(méi)有實(shí)際意義,完全是為了語(yǔ)法而語(yǔ)法。
接口代碼
//跑接口
type Runer interface {
Run()
}
// 跳接口
type Jumper interface {
Jump()
}
結(jié)構(gòu)體代碼
//袋鼠結(jié)構(gòu)體
type Roo struct {
Name string
}
func (this *Roo) Jump() {
fmt.Println("我是袋鼠,我會(huì)跳")
}
func (this *Roo) Run() {
fmt.Println("我是袋鼠,我會(huì)跑")
}
這個(gè)結(jié)構(gòu)體同時(shí)實(shí)現(xiàn)了兩個(gè)結(jié)構(gòu),一個(gè)是Runer,一個(gè)是Jumper。
main代碼
func main() {
var runner Runer
var jumper Jumper
runner = &Roo{Name: "袋鼠"}
jumper = &Roo{Name: "袋鼠"}
runner.Run()
jumper.Jump()
}
Roo既然實(shí)現(xiàn)了兩個(gè)接口,自然兩個(gè)接口都可以接收Roo這個(gè)結(jié)構(gòu)體。
執(zhí)行結(jié)果
接口嵌套
接口嵌套這個(gè)有點(diǎn)像組合,比如有跑,跳,吃等這些操作。
例如一個(gè)動(dòng)物,因該是要有這些操作的,那這個(gè)動(dòng)物應(yīng)該也是一個(gè)接口。
并且把這些動(dòng)作都拿過(guò)來(lái)才對(duì)。
接口示例代碼
//跑接口
type Runer interface {
Run()
}
// 跳接口
type Jumper interface {
Jump()
}
//動(dòng)物接口,繼承了 跑 和 跳
type Animal interface {
Runer
Jumper
}
結(jié)構(gòu)體代碼
//袋鼠結(jié)構(gòu)體,實(shí)現(xiàn)了跑和跳
type Roo struct {
Name string
}
func (this *Roo) Jump() {
fmt.Println("我是袋鼠,我會(huì)跳")
}
func (this *Roo) Run() {
fmt.Println("我是袋鼠,我會(huì)跑")
}
main代碼
func main() {
var animal Animal
animal = &Roo{Name: "袋鼠"}
animal = &Roo{Name: "袋鼠"}
animal.Run()
animal.Jump()
}
執(zhí)行結(jié)果
總結(jié)
上述我們學(xué)習(xí)了Go基礎(chǔ)的接口,主要學(xué)習(xí)了接口和繼承的區(qū)別,一個(gè)結(jié)構(gòu)體實(shí)現(xiàn)多個(gè)接口,接口嵌套。
可能不太好理解,但是一定要嘗試做一下,一定要堅(jiān)持!
如果在操作過(guò)程中有任何問(wèn)題,記得下面討論區(qū)留言,我們看到會(huì)第一時(shí)間解決問(wèn)題。
本文轉(zhuǎn)載自微信公眾號(hào)「Go語(yǔ)言進(jìn)階學(xué)習(xí)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Go語(yǔ)言進(jìn)階學(xué)習(xí)公眾號(hào)。
當(dāng)前標(biāo)題:一篇文章帶你了解Go語(yǔ)言基礎(chǔ)之接口
當(dāng)前URL:http://m.fisionsoft.com.cn/article/dpcdiec.html


咨詢(xún)
建站咨詢(xún)
