Go語言的接口應該如何理解呢?它和Java等其他語言的區別在哪裏呢?
答:其實Go語言的接口和其他一些面向對象編程的語言一樣,都是抽象方法的一個集合,不同點在於接口的實現和變量賦值。
接口的實現:與其他語言相比,GO中的接口實現並不需要顯示的聲明!
只要一個類型中包含有某一接口的全部方法,並且這些對應方法的命名、傳入參數和返回類型都完全匹配,那麼該類型就可以當做此接口的實現,不需要額外聲明。
type shaper interface {
area() float64
}
type circle struct {
radius float64
}
func (c *circle) area() float64{
return math.Pi * c.radius * c.radius
}
func main() {
circleA := circle{radius:10}
var shaperA shaper
shaperA = &circleA //對變量進行聲明
var shaperB shaper
shaperB = new(circle)
fmt.Println("圓A的面積是",shaperA.area())
fmt.Println("圓B的面積爲",shaperB.area())
}
結果爲:
圓A的面積是 314.1592653589793
圓B的面積爲 0
從示例可以看出來其實接口類型的變量本質上就是類似於指針。
實際上,接口類型的變量是一個複合數據結構:
第一部分指向接口的接受者,另一部分指向方法指針表。
對接口變量進行賦值:實際上會把實現該接口的類型的變量賦值給接受者,而方法指針表會獲得指向具體實現的方法的指針;
這樣程序在運行的過程中就知道某個接口類型的變量的方法的具體實現。接口是隱式的滿足匹配的。
多種類型可以實現同一個接口,實現了一個接口的某個類型還可以有另外的方法,可以實現多個接口;
注意:如果接口或者接口中的方法聲明是不可以導出的,則該接口方法無法被其他包中的類型所實現;
一些錯誤的接口實現:
1、沒有完全實現接口所定義的方法;
type shaper interface {
area() float64
perimeter() float64
}
type circle struct {
radius float64
}
func (c *circle) area() float64{
return math.Pi * c.radius * c.radius
}
func main() {
circleA := circle{radius:10}
var shaperA shaper
shaperA = &circleA //錯誤!因爲circle沒有實現perimeter方法
}
2、用某一類型的變量直接對接口進行賦值;
circleA := circle{radius:10}
var shaperA shaper
/**不可以直接將變量賦值給接口變量,在Java中這麼做是沒有問題的,
但是在Go中因爲接口類型的變量是一個類似與指針的東西,所以不能直接賦值;*/
shaperA = circleA
3、對不同包中具有不可導出方法 的接口進行實現;
空接口:
- 空接口就是沒有任何方法的接口,所以實現它們不需要任何的要求。因此一個空接口變量可以被任意賦值,從而指向任何類型的對象。
- 空接口的概念接近與Java中的object,即所有對象的基類。空接口變量可以指向基本類型,比如int、指針等等;
- 空接口可以被賦予任意類型的值,它的實際應用就是標準庫fmt裏的Printf()函數和Println()函數,通過配合使用空接口和類型查詢,能夠實現可接受任意對象實例並進行處理的函數;
個人github:https://github.com/SpecialAll