Golang 也有面向对象编程的继承,封装和多态的特性,只是它是以 struct结构体来实现的。
继承可以解决代码的复用问题。
一个 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() ---简单的继承
}
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: {手机} &{北京 红米}
}