继承注意事项
继承注意事项
-
结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。
package main import ( "fmt" ) //定义动物结构体 type Animal struct { Age int weight float32 } //给Animal结构体添加一个方法:喊叫 func (a *Animal) Shout() { fmt.Println("我可以大喊大叫") } //给绑定方法:自我展示: func (a *Animal) showInfo() { fmt.Println("年龄:", a.Age, "体重:", a.weight) } //定义结构体:cat type Cat struct { // 继承Animal Animal } //给Cat绑定特有方法: func (c *Cat) scratch() { fmt.Println("我是猫,我可以挠人") } func main() { cat := &Cat{} cat.Animal.Age = 3 cat.Animal.weight = 4.5 cat.Animal.Shout() cat.Animal.showInfo() cat.scratch() } -
匿名结构体字段访问可以简化。
func main() { cat := &Cat{} cat.Animal.Age = 3 cat.Animal.weight = 4.5 cat.Animal.Shout() cat.Animal.showInfo() cat.scratch() }等价于
func main() { cat := &Cat{} cat.Age = 3 cat.weight = 4.5 cat.Shout() cat.showInfo() cat.scratch() }cat.Age --->cat对应的结构体中找是否有Age字段,如果有直接使用,如果没有就去找嵌入的结构体类型中的Age
-
当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。
package main import ( "fmt" ) //定义动物结构体 type Animal struct { Age int weight float32 } //给Animal结构体添加一个方法:喊叫 func (a *Animal) Shout() { fmt.Println("我可以大喊大叫") } //给绑定方法:自我展示: func (a *Animal) showInfo() { fmt.Println("年龄:", a.Age, "体重:", a.weight) } //定义结构体:cat type Cat struct { // 继承Animal Animal Age int } func (c *Cat) showInfo() { fmt.Println("----年龄:", c.Age, "----体重:", c.weight) } //给Cat绑定特有方法: func (c *Cat) scratch() { fmt.Println("我是猫,我可以挠人") } func main() { // cat := &Cat{} // cat.Age = 3 // cat.weight = 4.5 // cat.Shout() // cat.showInfo() // cat.scratch() cat := &Cat{} cat.weight = 4.5 cat.Age = 3// 这里的cat.Age会覆盖Animal中的Age,就近调用 cat.showInfo()// 调用Cat的showInfo方法,就近调用 cat.Animal.Age = 20 cat.Animal.showInfo() // 调用Animal的showInfo方法 } -
Golang中支持多继承:如一个结构体嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。为了保证代码的简洁性,建议大家尽量不使用多重继承,很多语言就将多重继承去除了,但是Go中保留了。
package main import ( "fmt" ) type A struct { a int b string } type B struct { c int d string } type C struct { A B } func main() { //构建C的实例 c := C{A{10,"aaa"},B{20,"bbb"}} fmt.Println(c) } -
如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。
package main import ( "fmt" ) type A struct { a int b string } type B struct { c int d string a int } type C struct { A B } func main() { //构建C的实例 c := C{A{10,"aaa"},B{20,"bbb",50}} fmt.Println(c.b) fmt.Println(c.A.a) } -
结构体的匿名字段是基本数据类型。
type C struct {
A
B
int
}
func main() {
//构建C的实例
c := C{A{10,"aaa"},B{20,"bbb",50},888}
fmt.Println(c.b)
fmt.Println(c.A.a)
fmt.Println(c.int)
}
-
嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值。
func main() { //构建C的实例 c := C{ A{ a:10, b:"aaa", }, B{ c:20, d:"bbb", a:50}, 888} fmt.Println(c.b) fmt.Println(c.A.a) fmt.Println(c.int) } -
嵌入匿名结构体的指针也是可以的。
func main() { //构建C的实例 c := C{ A{ a:10, b:"aaa", }, B{ c:20, d:"bbb", a:50}, 888} fmt.Println(c.b) fmt.Println(c.A.a) fmt.Println(c.int) c1:= C1{&A{10,"aaa"},&B{20,"bbb",50},888} fmt.Println(*c1.A) fmt.Println(*c1.B) } -
结构体的字段可以是结构体类型的。(组合模式)
type D struct { a int//嵌入A组合模式 b string c B //嵌入B组合模式 } func main() { //构建C的实例 d := D{10,"ooo",B{66,"bbb",99}} fmt.Println(d) fmt.Println(d.c.d)

浙公网安备 33010602011771号