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