什么是接口
在go語言中牵寺,接口是一組方法的集合,但不包含方法的實現(xiàn)家肯、是抽象的,接口中也不能包含變量
當(dāng)一個類型T提供了接口中所有方法的定義時盟猖,就說T實現(xiàn)了接口讨衣,并不用顯示的聲明實現(xiàn)了某個接口。
接口指定類型有哪些方法式镐,類型決定如何去實現(xiàn)這些方法
go語言的接口跟其他語言接口的區(qū)別
go語言接口是隱式實現(xiàn)的反镇, 實現(xiàn)了接口的方法就算實現(xiàn)了這個接口。引入了動態(tài)語言的便利娘汞。
java語言等靜態(tài)語言接口是先定義一個接口歹茶,然后顯示其他類要實現(xiàn)這個接口,并重寫改接口的方法。
python這種動態(tài)語言本來就沒有接口這一定義的辆亏,因為他是動態(tài)語言风秤,里面的類型都是動態(tài)類型。
這樣實現(xiàn)的一個好處就是扮叨,靈活缤弦、松耦合。每個類更需要關(guān)注自己的實現(xiàn)彻磁,不需要導(dǎo)入一下必要的包碍沐,不需要考慮接口的實現(xiàn)≈则眩可以實現(xiàn)了調(diào)用方定義接口累提,實現(xiàn)方關(guān)注具體實現(xiàn)。
注:動態(tài)語言的特點
變量綁定的類型是不確定的磁浇,在運行期間才能確定
函數(shù)和方法可以接收任何類型的參數(shù)斋陪,且調(diào)用時不檢查參數(shù)類型
不需要實現(xiàn)接口
接口聲明
#用interface來定義接口
type Name interface{
Method1(params) return_type
Method2(params) return_type
}
#實際的例子
type Shap interface{
Area() float32
}
考點一:接口動態(tài)類型和動態(tài)值
接口其實是一種類型,可以創(chuàng)建接口類型的變量置吓,例如:
func main(){
var s Shape
fmt.Println("value of s is", s) //value of s is <nil>
fmt.Println("type of s is %T\n", s) //type of s is <nil>
- 靜態(tài)類型:變量的類型在聲明時指定无虚,且不能改變
- 動態(tài)類型:反之
而接口的靜態(tài)類型就是接口本身,接口沒有靜態(tài)值衍锚,它指向的是動態(tài)值友题。
接口類型的變量,存的是實現(xiàn)接口的類型值(該值就是接口的動態(tài)值)戴质,實現(xiàn)接口的類型就是接口的動態(tài)類型度宦。
type Iname interface{
Mname()
}
#St1 類型實現(xiàn)了接口Iname
type St1 struct{}
func (St1) Mname() {}
#St2 類型也實現(xiàn)了接口Iname
type St2 struct{}
func (St2) Mname(){}
func main() {
var i Iname = St1{} //type is Stu, value is {}
i = St2{} //type is Stu, value is {}
}
變量i的靜態(tài)類型是Iname,是不能改變的告匠,動態(tài)類型卻不是固定的
- 只有當(dāng)接口的動態(tài)類型和動態(tài)值都為nil的時候戈抄,接口才為nil
考點二:值接收者和指針接收者
值類型既可以調(diào)用值接收者的方法,也可以調(diào)用指針接收者的方法
指針類型既可以調(diào)用指針接收者的方法后专,也可以調(diào)用值接收者的方法
實現(xiàn)了接收者的值類型方法呛凶,相當(dāng)于自動實現(xiàn)了接收者的指針類型方法
而實現(xiàn)了接收者的指針類型的方法,不會自動生成對應(yīng)接收者是值類型的方法
如果實現(xiàn)了接收者是值類型的方法行贪,會隱含地也實現(xiàn)了接收者是指針類型的方法漾稀。
考點三:斷言 與 類型轉(zhuǎn)換
類型轉(zhuǎn)換、類型斷言本質(zhì)都是把一個類型轉(zhuǎn)換成另外一個類型建瘫。
go語言中不允許隱式的類型轉(zhuǎn)換崭捍。
斷言要用comba, ok啰脚,直接轉(zhuǎn)換會引起panic
考點四:接口組合
- 細(xì)粒度的接口殷蛇,io.Write实夹、io.Read、io.ReadWrite
- 在一個接口中粒梦,定義另外一個接口亮航,就會擁有另外一個接口的所有變量