继承注意事项

继承注意事项

  1. 结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。

    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()
    }
    
  2. 匿名结构体字段访问可以简化。

    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

  3. 当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。

    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方法
    }
    
  4. 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)
    }
    
  5. 如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分。

    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)
    }
    
  6. 结构体的匿名字段是基本数据类型。

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)
}
  1. 嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值。

    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)
    }
    
  2. 嵌入匿名结构体的指针也是可以的。

    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)
    }
    
  3. 结构体的字段可以是结构体类型的。(组合模式)

    
    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)
    

posted @ 2025-07-02 18:13  hutaodd  阅读(9)  评论(0)    收藏  举报