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 }
留言
張貼留言