Field and Method Overriding in Go

Go语言可以通过嵌入实现继承。外层结构体可自动拥有被嵌入结构体的字段和方法

在使用嵌入实现继承时,字段和方法都可以被覆盖。如果没有被覆盖,可以通过外层直接一次访问到。如果被覆盖了,无论是字段还是方法,都需要显式精确制定到内部。

这里的字段在其他语言中可以理解为实例变量

字段覆盖

package main

import "fmt"

//
type Person struct {
	Age  int
	Name string
}

// 字段覆盖例子。
// 如果想引用内层字段,需要显示引用
// Student has a same field `Age` with Person
type Student struct {
	Person
	Age int
}

func main() {
	p := Person{12, "lily"}
	fmt.Println(p)

	s := Student{Person{12, "lily"}, 19}
	fmt.Println(s)
	fmt.Println(s.Person.Age)
	fmt.Println(s.Age)
	fmt.Println(s.Name)
	fmt.Println(s.Person.Name)

}

output:

{12 lily}
{{12 lily} 19}
12
19
lily
lily

方法覆盖

// 方法覆盖例子

package main

import "fmt"

type Person struct {
	age int
}

type Student struct {
	Person
}

func (p *Person) GrowUp() {
	p.age = p.age + 1
}

func (p *Student) GrowUp() {
	p.age = p.age + 3
}

func newPerson(age int) *Person {
	return &Person{age}
}

func main() {
	// person
	p := newPerson(12)
	fmt.Println(p.age)
	p.GrowUp()
	fmt.Println(p.age)

	// student
	s := &Student{Person{16}}
	fmt.Println(s.age)
	// 显示调用内层方法
	s.Person.GrowUp()
	fmt.Println(s.age)
	// 调用被覆盖后的新方法
	s.GrowUp()
	fmt.Println(s.age)

}

output:

12
13

16
17
20