Golang并非设计成了一种面向对象的语言,没有Class的概念,因此在继承和多态的实现上有些让人难以快速理解的地方。

首先看继承的实现,以经典的学生-小学生-大学生为例:

type Student struct {
    Name string     //姓名
    Age int         //年龄
    Score int   //成绩
}

type Pupil struct {
    Student
}

type Graduate struct {
    Student
}

这样就实现了继承。因为Pupil和Graduate都能够使用到父类(父结构体)。

实现了继承,就可以实现多态,一般的多态可以用这样的类图来表示:

对于Java来说实现起来很简单,如果利用Golang的interface,实现起来也不是很难:

package person

import "fmt"

type Student struct {
    Name string     //姓名
    Age int         //年龄
    Score int   //成绩
}

type Pupil struct {
    Student
}

type Graduate struct {
    Student
}

type Study interface {
    Exam()
}

func (t *Pupil) Exam() {
    fmt.Printf("小学生%s在考试\n", t.Name)
}

func (t *Graduate) Exam() {
    fmt.Printf("大学生%s在考试\n", t.Name)
}

这样Pupil和Graduate都实现了Study接口,用main函数调用:

func main() {
    s := &person.Pupil{}
    s.Student.Name = "zhiquan"
    s.Student.Age = 12
    s.Student.Score = 100
    s.Exam()

    g := &person.Graduate{}
    g.Student.Name = "Lee"
    g.Student.Age = 22
    g.Student.Score = 85
    g.Exam()
}

从另一个角度来说,这实际上确实实现了多态。同一种父类下不同的实现,实现了不同的方法。

如果说struct对应Java里的Class的话,那么就比较好理解了,实际上就是Struct实现了接口,只不过接口里定义的行为没办法在Struct里实现,只能在其他地方实现。