Go(7) - anonymous field, 組合與繼承

Anonymous field 可以把一個型別(如: int, struct) 加到一個 struct 裡,該 struct 呼叫 anonymous field 的型別等於呼叫 anonymous field。

包含 anonymous field 的 struct 可以使用 anonymous field 的 field 及 function。

1. Anonymous field:

定義 Foo 包含一個型別為 string 的 anonymous field。

由於 Anonymous field 沒有名稱,所以呼叫時要利用型別名稱呼叫。

type Foo struct {
    string
}

func main() {
    f := Foo{"Bar"}
    fmt.Println(f.string) // "bar"
}

2. 將 struct 當成 anonymous field:

定義新型別 Animal 並將其當成Dog 的 anonymous field。

type Animal struct {
    Name string
    Age  int
}

type Dog struct {
    Animal
    Breed string
}

func main() {
    d := Dog{Animal{"White", 10}, "beagles"}
    fmt.Println(d.Animal.Name)
    fmt.Println(d.Name)
}

初始化 Dog 時相對麻煩,要將 Animal 實例化後傳入。

Dog 呼叫 Animal 的 field 時可以省略 Animal,類似我們繼承一個類後可以使用該類的屬性。


3. 透過 anonymous field 組合並繼承:

若 anonymous field 的對象是 struct 還可以使用該 struct 的方法。

type Animal struct {
    Name string
    Age  int
}

func (a *Animal) ToString() string {
    return fmt.Sprintf("Name: %s, Age: %d", a.Name, a.Age)
}

type Dog struct {
    Animal
    Breed string
}

func main() {
    d := Dog{Animal{"White", 10}, "beagles"}
    fmt.Println(d.Animal.ToString()) // Name: White, Age: 10
    fmt.Println(d.ToString()) // Name: White, Age: 10
}

4. anonymous field 和 override:

Go 中透過 anonymous field 組合的效果比較類似 JS 的 prototype chain。

如果當前的 struct 不包含該方法時 才會去 anonymous field 尋找函式。

type Animal struct {
    Name string
    Age  int
}

func (a *Animal) ToString() string {
    return fmt.Sprintf("Name: %s, Age: %d", a.Name, a.Age)
}

type Dog struct {
    Animal
    Breed string
}

func (d *Dog) ToString() string {
    return fmt.Sprintf("Name: %s, Age: %d, Breed: %s", d.Name, d.Age, d.Breed)
}

func main() {
    d := Dog{Animal{"White", 10}, "beagles"}
    fmt.Println(d.Animal.ToString()) // Name: White, Age: 10
    fmt.Println(d.ToString()) // Name: White, Age: 10, Breed: beagles
}

留言

熱門文章