Skip to content

Latest commit

 

History

History
102 lines (84 loc) · 3.35 KB

interfaces.md

File metadata and controls

102 lines (84 loc) · 3.35 KB

Go by Example: Interfaces

界面 是方法集合的別稱
它的主要作用在於類似『物件』的使用,我們還是直接看範例吧。

package main

import (
    "fmt"
    "math"
)

type geometry interface {	// 可以想成.....幾何類別
    area() float64		// 按照上面的原文,又可以說是『方法集合』
    perim() float64		// 也就是說,在界面中,只需要定義『方法』即可
}

type rect struct {		// 幾何形狀之一:矩形
    width, height float64
}
type circle struct {		// 幾何形狀之一:圓
    radius float64
}

func (r rect) area() float64 {	// 幾何形狀的方法:面積
    return r.width * r.height
}
func (r rect) perim() float64 {	// 幾何形狀的方法:周長
    return 2*r.width + 2*r.height
}

func (c circle) area() float64 { // 幾何形狀的方法:面積
    return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {// 幾何形狀的方法:周長
    return 2 * math.Pi * c.radius
}

func measure(g geometry) {	// 普通方法,利用共同界面 geometry
    fmt.Println(g)		// 
    fmt.Println(g.area())	// 就可以不管原來結構,呼叫界面中的方法
    fmt.Println(g.perim())	// 這作法很像 OOP 中的繼承
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}

    measure(r)			// 矩形跟圓形有共同的界面
    measure(c)			// 所以可以透過 measure() 呼叫界面中的方法

    g := make([]geometry, 0)	// 『幾何』陣列
    g = append(g, r)		// 可以把矩形丟入幾何陣列
    g = append(g, c)		// 再把圓形丟入幾何陣列中,
				// 界面讓 Go 的陣列可以不必被限制統一結構
    for _, s := range g {	// 這時候可以呼叫界面中定義的方法
        fmt.Println(s.area(), s.perim())
    }
}

執行

$ go run interfaces.go
{3 4}
12
14
{5}
78.53981633974483
31.41592653589793

Go 語言的界面是相當強大的特性,可以說寫個稍微不那麼小的程式都會用到
有興趣的話,請參考如何使用 Go 語言的界面一文

這邊再回憶一下前面提到的結構方法, 這兩個 Go 語言特性使得它具有物件導向的基礎,加上界面的使用,使得 Go 語言效能與結構化設計能同時具備。

以本範例來思考,界面可以想成是類別中最小的共同方法集合。
事實上,界面讓 Go 語言具備繼承的概念:界面中含有界面成員:

type IGeometry interface {
    geometry
    name() string
    setName(string)
}
.... 參考上例 ....
    r := rect{width: 3, height: 4}
    r.SetName("table")
    c := circle{radius:5}
    c.SetName("wheel")
.... , 參考上例 ....
    for _, s := range g {
        fmt.Println(s.Name(), s.area(), s.perim())
    }

以上摘要來自用介面 (Interface) 實踐繼承和多型
底下先插個話,界面感覺是物件的一部份,而 Go 語言的多型不常見,只有 String() 最特別,我們將在後面錯誤處理看到類似多型的用法。如果結構定義了 String() 方法的話,就可以將該物件透過 fmt.Println(v) 印出訊息。

下一範例: Errors