Golang的继承和多态实现

2023-04-06 08:27:02 浏览数 (1)

1. 基本实现

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

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

代码语言:go复制
type Student struct {
    Name string     //姓名
    Age int         //年龄
    Score int   //成绩
}

type Pupil struct {
    Student
}

type Graduate struct {
    Student
}

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

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

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

代码语言:go复制
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函数调用:

代码语言:go复制
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里实现,只能在其他地方实现。

2. 函数的显式类型转换

“函数是一等公民”这个说法是Golang领域的一个重要概念,所谓的“一等公民”,我现在的理解,那无非是函数可以像一个基本类型一样使用,比如当做参数来传递,也可以当做一种类型来使用。

这种代码在Go的世界里是会报错的:

代码语言:go复制
var a int = 3
var b int32 = 5
fmt.Println(a   b)

就是类型不匹配,因此需要转换一下子:

代码语言:go复制
var a int = 3
var b int32 = 5
fmt.Println(a   int(b))

在《Go语言精进之路》这本书里,提到了一个概念叫做:函数是一等公民。

就是说函数在Go中很重要,很灵活,可以像一个变量一样使用。

比如下面这段代码:

代码语言:go复制
package main

import "fmt"

type BinaryAdder interface {
	Add(int, int) int
}

type MyAdderFunc func(int, int) int

func (f MyAdderFunc) Add(x, y int) int {
	return f(x, y)
}

func MyAdd(x, y int) int {
	return x   y
}

func main() {
	var i BinaryAdder = MyAdderFunc(MyAdd)
	fmt.Println(i.Add(1, 2))
}

在20行的地方进行了一次显式的类型转换,将MyAdd转换成了MyAdderFunc类型,而MyAdderFunc实现了BinaryAdder接口,因此可以完成20行的赋值语句。

这就是一种多态的实现,继承了BinaryAdder接口的类MyAdderFunc是可以向上转型的。和之前的多态例子不谋而合。

go

0 人点赞