很多从别语言转过来的同学,都会问,Go 里面有继承么?
那必须没有呀,不然怎么牛逼呀,哈哈。
Go 语言里面没有继承,如果谁给你说,Go 语言有继承你可以直接拉黑他了。
但是继承这个特性,真的很好用,很重要的一个特性,那 Go 语言是怎么处理这个特性的呢?
靠嵌套,只要我们嵌套了他,那我就拥有了他,从而间接实现了类似继承的特性。
一、嵌套结构体
咱举个例子,我们这个定义一个人类:
代码语言:javascript复制type People struct {
Name string //名字
}
然后我再定义一个学生:
代码语言:javascript复制type Student struct {
SId string //学号
}
目前这两个结构体没任何交集,实际上学生也是人类,所以他应该也有人类的属性。
所以如果其他语言里面 学生 就可以继承 人类。
Go 里面没继承,就直接嵌套,学生里面嵌套一个人类:
代码语言:javascript复制type Student struct {
People
SId string //学号
}
这样我们在使用 Student 时也就有了人类的属性:
二、嵌套的一些特点
1、赋值
虽然我们可以直接通过点,取得对应的属性,但是在初始化时却不能。
你会发现找不到 Name 这个属性,我们只能结构体方式赋值:
大家多谢谢就熟练了哈。
如果你不是这种方式赋值,通过点的方式赋值,并不影响:
2、JSON
不仅赋值奇怪了点,转成 JSON 更奇怪。
我们现在给我们的结构体打上 Tag,然后转化成 JSON 字符串看看:
代码语言:javascript复制type People struct {
Name string `json:"name"` //名字
}
type Student struct {
People
SId string `json:"s_id"` //学号
}
func main() {
stu := &Student{
People: People{Name: "张三"},
SId: "N123",
}
fmt.Println(stu)
b, _ := json.Marshal(stu)
fmt.Println(string(b))
}
执行下看下结果:
代码语言:javascript复制$ go run tt.go
&{{张三} N123}
{"name":"张三","s_id":"N123"}
你会发现,如果直接打印结构体是能看到嵌套的,但是转成 JSON 时,却看不到嵌套的身影。
这个特性我们也可以反过来用!
代码语言:javascript复制func main() {
// 模拟用户提交的数据
jsonStr := `{"name":"张三","s_id":"N123"}`
stu := &Student{}
json.Unmarshal([]byte(jsonStr), &stu)
fmt.Println(stu)
}
执行下结果:
代码语言:javascript复制$ go run tt.go
&{{张三} N123}
你会发现,自动给嵌套的结构体赋值了。
3、方法
被嵌套的结构体方法,在嵌套的结构体上同样可以使用。
请看下面代码:
代码语言:javascript复制type People struct {
Name string `json:"name"` //名字
}
func (this *People) GetName() string {
return this.Name
}
type Student struct {
People
SId string `json:"s_id"` //学号
}
func main() {
stu := &Student{
People: People{Name: "王五"},
SId: "N34",
}
name := stu.GetName() //通过方法获取
fmt.Println(name)
}
GetName
这个方法,在嵌套的 Student
上同样能调用。
于是我们可以衍生,是否能用这个属性去处理公共的接口呢?
感兴趣的同学可以去实操试试!