09.03-Interface

Interfaces

你可能已經注意到,我們可以將 Rectangle 的 area method 命名為 Circle 的 area method。這並非意外。在真實世界設計程式時,像這類的相似關係,Go 語言提供了一種所謂的 Interface 型別,這裡有一個 Shape 介面的範例:

type Shape interface {
    area() float64
}

Interface 與 struct 一樣,都是使用 type 關鍵字建立的,後面跟著一個名稱,以及關鍵字 interface。不過這裡不定義欄位,而是定義一組 method,一組 method 指的是一串 methods,為了要實做 interface,所以這些 methods 都要有一個型別。

在我們的 Rectangle 與 Circle 範例中,都有 area method,而且會傳回 float64,所以這兩個型別都有實做 Shape interface。對它自己本身而言,這樣做並不會有什麼好處,不過我們可以使用 interface 型別做為函式的參數:

func totalArea(shapes ...Shape) float64 {
    var area float64
    for _, s := range shapes {
        area += s.area()
    }
    return area
}

我們會像這樣呼叫這個函式:

fmt.Println(totalArea(&c, &r))

也可以將 interface 做為欄位使用:

type MultiShape struct {
    shapes []Shape
}

我們甚至可以透過提供 MultiShape 一個 area method,將它自己轉為 Shape

func (m *MultiShape) area() float64 {
    var area float64
    for _, s := range m.shapes {
        area += s.area()
    }
    return area
}

現在,一個 MultiShape 就包含了 CircleRectangle、或甚至是其它的 MultiShape

Comments