golang interface接口

package main

import "fmt"

type Shaper interface {
	Area() float32
}

type Square struct {
	side float32
}

func (sq *Square) Area() float32 {
	return sq.side * sq.side
}

func main() {
	sq1 := new(Square)
	sq1.side = 5

	var areaIntf Shaper
	areaIntf = sq1
	// shorter,without separate declaration:
	// areaIntf := Shaper(sq1)
	// or even:
	// areaIntf := sq1
	fmt.Printf("The square has area: %f\n", areaIntf.Area())
}

  

上面的程序定義了一個結構體 Square 和一個接口 Shaper,接口有一個方法 Area()編程

在 main() 方法中建立了一個 Square 的實例。在主程序外邊定義了一個接收者類型是 Square 方法的 Area(),用來計算正方形的面積:結構體 Square 實現了接口 Shaper 。數組

因此能夠將一個 Square 類型的變量賦值給一個接口類型的變量:areaIntf = sq1 。ide

如今接口變量包含一個指向 Square 變量的引用,經過它能夠調用 Square 上的方法 Area()。固然也能夠直接在 Square 的實例上調用此方法,可是在接口實例上調用此方法更使人興奮,它使此方法更具備通常性。接口變量裏包含了接收者實例的值和指向對應方法表的指針。oop

這是 多態 的 Go 版本,多態是面向對象編程中一個廣爲人知的概念:根據當前的類型選擇正確的方法,或者說:同一種類型在不一樣的實例上彷佛表現出不一樣的行爲。this

若是 Square 沒有實現 Area() 方法,編譯器將會給出清晰的錯誤信息:lua

cannot use sq1 (type *Square) as type Shaper in assignment:
*Square does not implement Shaper (missing Area method)

  若是 Shaper 有另一個方法 Perimeter(),可是Square 沒有實現它,即便沒有人在 Square 實例上調用這個方法,編譯器也會給出上面一樣的錯誤。spa

擴展一下上面的例子,類型 Rectangle 也實現了 Shaper 接口。接着建立一個 Shaper 類型的數組,迭代它的每個元素並在上面調用 Area() 方法,以此來展現多態行爲:指針

package main

import "fmt"

type Shaper interface {
	Area() float32
}

type Square struct {
	side float32
}

func (sq *Square) Area() float32 {
	return sq.side * sq.side
}

type Rectangle struct {
	length, width float32
}

func (r Rectangle) Area() float32 {
	return r.length * r.width
}

func main() {

	r := Rectangle{5, 3} // Area() of Rectangle needs a value
	q := &Square{5}      // Area() of Square needs a pointer
	// shapes := []Shaper{Shaper(r), Shaper(q)}
	// or shorter
	shapes := []Shaper{r, q}
	fmt.Println("Looping through shapes for area ...")
	for n, _ := range shapes {
		fmt.Println("Shape details: ", shapes[n])
		fmt.Println("Area of this shape is: ", shapes[n].Area())
	}
}

  在調用 shapes[n].Area() 這個時,只知道 shapes[n] 是一個 Shaper 對象,最後它搖身一變成爲了一個 Square 或 Rectangle 對象,而且表現出了相對應的行爲。code

在調用 shapes[n].Area() 這個時,只知道 shapes[n] 是一個 Shaper 對象,最後它搖身一變成爲了一個 Square 或 Rectangle 對象,而且表現出了相對應的行爲。對象

package main

import "fmt"

type stockPosition struct {
	ticker     string
	sharePrice float32
	count      float32
}

/* method to determine the value of a stock position */
func (s stockPosition) getValue() float32 {
	return s.sharePrice * s.count
}

type car struct {
	make  string
	model string
	price float32
}

/* method to determine the value of a car */
func (c car) getValue() float32 {
	return c.price
}

/* contract that defines different things that have value */
type valuable interface {
	getValue() float32
}

func showValue(asset valuable) {
	fmt.Printf("Value of the asset is %f\n", asset.getValue())
}

func main() {
	var o valuable = stockPosition{"GOOG", 577.20, 4}
	showValue(o)
	o = car{"BMW", "M3", 66500}
	showValue(o)
}

  數據類型實現了接口,就能使用以接口變量爲參數的方法

備註:

有的時候,也會以一種稍微不一樣的方式來使用接口這個詞:從某個類型的角度來看,它的接口指的是:它的全部導出方法,只不過沒有顯式地爲這些導出方法額外定一個接口而已。

相關文章
相關標籤/搜索