当前位置: 首页 > 工具软件 > BStruct > 使用案例 >

golang struct的继承

夏骏
2023-12-01

golang struct的继承

Golang 也有面向对象编程的继承,封装和多态的特性,只是它是以 struct结构体来实现的。

继承可以解决代码的复用问题。

1.继承的简单实现

一个 struct嵌套 另一个匿名struct,那么这个结构体就可以直接访问匿名struct的字段和方法,从而实现继承特性

// Student 父结构体
type Student struct {
	Name string
	age int
}

// ShowInfo 父结构体的方法
func (s *Student) ShowInfo() {
	fmt.Printf("学生信息:name=%v, age=%v\n", s.Name, s.age)
}

// Pupil 小学生
type Pupil struct {
	Student          // 嵌入 Student匿名结构体, 从而实现继承
	Skill string
}

func (p *Pupil) testing() {
	fmt.Println("小学生正在考试中.....")
}

func main()  {
	pu := &Pupil{Skill: "sing"}
	pu.Name = "tom"          // 也可以: pu.Student.Name = "tom"
	pu.age = 9

	pu.testing()
	pu.ShowInfo()            // 也可以: pu.Student.ShowInfo();
	// pu.Student.ShowInfo();
	// 调用 Student 函数可以简化为 pu.ShowInfo() ---简单的继承
}

2.继承的深入理解

  • 结构体可以使用嵌套结构体所有的字段和方法,不管首字母大写或小写,都可以使用。如上面示例:
pu := &Pupil{Skill: "sing"}
pu.age = 9      // age 是一个首字母小写的字段,子类也能直接调用
  • 匿名结构体字段访问可以简化
pu := &Pupil{Skill: "sing"}
pu.Student.Name = "tom"       // 简化: pu.Name = "tom"
pu.Student.ShowInfo()         // 简化: pu.ShowInfo()
  • 当结构体和匿名结构体有相同的字段或方法时,编译器采用就近访问原则
var b B
b.name = "tom"    // 采用就近原则,会访问 B结构体的name字段
b.A.name = "jack" // 明确指定访问 A结构体的name字段
// ===== 访问函数也是一样的方式 ======
b.say()           // 采用就近原则
b.A.say()         // 明确指定访问 A结构体的say()函数
  • 嵌入两个(或多个)匿名结构体,如果两个匿名结构体有相同的字段和方法(同时结构体
    本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。
type A struct { Name string }
type B struct { Name string }
type C struct {
	A             // 嵌入匿名结构体
	B
}
var c C
// 当多个结构体有相同字段或方法时,必须明确指定访问的结构体名称
c.A.Name = "tom"    // 当前访问的是 A结构体的Name字段
  • 结构体嵌套了一个有名结构体,这种关系是组合关系,那么在访问字段或方法时,必须带上结构体的名称
type B struct {
	  a A      // 有名结构体,不是一种继承关系,而是一种组合关系(A结构体其实就是 B结构体的一个字段属性而已)
}
// 访问有名结构体的字段时,必须带上有名结构体的名称
var b B
b.a.Name = "tom"
  • 嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值,即直接初始化匿名结构体
// Goods 商品
type Goods struct {
	Name string
}
// Brand 品牌
type Brand struct {
	addr string
	Name string
}
type Iphone struct {
	Goods             // 嵌入匿名结构体
	*Brand            // 嵌入的匿名结构体也可以是 指针类型
}
func main()  {
	redmi := Iphone{
		Goods{"手机"},
		&Brand{ "北京", "红米"},    // 指针类型,赋值也必须是指针的赋值
	}
	fmt.Println("iphone: ", redmi.Goods, redmi.Brand)
	// 打印:  iphone:  {手机} &{北京 红米}
}
 类似资料: