6.2 Go 匿名字段

Golang匿名字段:可以像访问字段成员那样,访问匿名字段方法,go编译器自动查找。

package main

import "fmt"

type Student struct {
    id   int
    name string
}

type Teacher struct {
    //匿名字段
    Student
}

func (s1 *Student) Play() {
    fmt.Printf("Student地址:%p,值是%v\n", s1, s1)
    fmt.Println("我是个学生,但是我就爱玩儿,你能奈我何")
}
func main() {
    t1 := &Teacher{Student{1, "银角大王吧"}}
    //两种方式一样效果
    /*
        t1 := &Teacher{
            Student{
                1,
                "银角大王吧",
            },
        }
    */
    fmt.Printf("t1的内存地址:%p\n", &t1)
    //通过t1变量,执行结构体Student的方法,查找
    t1.Play() //  t1 -> Teacher -> *Student
}

通过匿名字段可以实现

重写 override

1.1. Go继承实战

写一个学生管理系统,学生类别有(小学生、中学生、大学生),既然是学生群体都可以(查询成绩、设置成绩)

package main

import "fmt"

//学生结构体
type Student struct {
    Name  string
    Age   int
    Score int
}

//显示学生个人信息方法,接收指针类型
func (stu *Student) ShowInfo() {
    fmt.Printf("学生姓名:%v 年龄=%d 成绩=%d\n", stu.Name, stu.Age, stu.Score)
}

//设置学生成绩
func (stu *Student) SetScore(score int) {
    stu.Score = score
}

//小学生群体 单词pupil
type Pupil struct {
    //小学生的属性完全可以继承Student学生的属性
    Student //继承匿名字段
}

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

//大学生结构体,同样的也有学生的常见属性
type Graduate struct {
    Student
}

//大学生独有的方法
func (g *Graduate) testing() {
    fmt.Println("大学生正在答辩考试中...")
}

func main() {
    p1 := &Pupil{Student{"小学生一号", 7, 99}}
    p1.testing()
    p1.ShowInfo()
    p1.SetScore(100)
    p1.ShowInfo()
    fmt.Println("-----------")
    g1 := &Graduate{Student{"大学生一号", 22, 50}}
    g1.testing()
    g1.ShowInfo()
    g1.SetScore(60)
    g1.ShowInfo()
}
代码的复用性

注意点:

如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现继承
如果一个struct嵌套了另一个【有名】的结构体,那么这个模式叫做组合