Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

Go的进阶学习

2021/12/29
Word count: 777 | Reading time: 3min

GO中通过组合方式实现的伪继承

说到继承我们都知道,也可以了解到在Go中是没有extends关键字的,也就意味着Go并没有原生级别的继承支持。这也是为什么用了伪继承这个词。本质上,Go使用interface实现的功能叫组合,Go是通过组合(+匿名字段的技术)来实现的继承,说的更精确一点,是使用组合来代替继承

我们用很容易理解的动物-来举例子,废话不多说,直接看代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Animal struct {
Name string
}

func (a *Animal) Eat() {
fmt.Printf("%v is eating", a.Name)
fmt.Println()
}

type Cat struct {
*Animal
}

cat := &Cat{
Animal: &Animal{
Name: "cat",
},
}
cat.Eat() // cat is eating

代码分析

首先,我们实现了一个Animal的结构体,代表动物类。并声明了Name字段,用于描述动物的名字。然后,实现了一个以Animal为receiver的Eat方法,来描述动物进食的行为。最后,声明了一个Cat结构体,组合了Cat字段。再实例化一个猫,调用Eat方法,可以看到会正常的输出。

可以看到,Cat结构体本身没有Name字段,也没有去实现Eat方法。唯一有的就是组合了Animal父类,至此,我们就证明了已经通过组合实现了继承。

将接口优雅简明化

接口用于描述某个类的行为。对于一个接口的使用者而言,我需要在拿到这个接口的同时能一目了然的知道这个类干了什么,有哪些方法可以调用,因此上面的写法我们并不能从中看出Animal具体有哪些功能,因此,我们可以创建一个说明它功能方法的父接口。

例如,我们即将要抽象的动物接口就会描述作为一个动物,具有哪些行为。常识告诉我们,动物可以进食(Eat),可以发出声音(bark),可以移动(move)等等。这里有一个很有意思的类比。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 模拟动物行为的接口
type IAnimal interface {
Eat() // 描述吃的行为
}

// 动物 所有动物的父类
type Animal struct {
Name string
}

// 动物去实现IAnimal中描述的吃的接口
func (a *Animal) Eat() {
fmt.Printf("%v is eating\n", a.Name)
}

// 动物的构造函数
func newAnimal(name string) *Animal {
return &Animal{
Name: name,
}
}

// 猫的结构体 组合了animal
type Cat struct {
*Animal
}

// 实现猫的构造函数 初始化animal结构体
func newCat(name string) *Cat {
return &Cat{
Animal: newAnimal(name),
}
}

cat := newCat("cat")
cat.Eat() // cat is eating

函数形参问题

1
2
3
4
5
6
7
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// ...
c := newContext(w, req)
c.handlers = middlewares
c.engine = engine
engine.router.handle(c)
}

这里和 http ServerHTTP 函数原始的两个参数对应 req 和 writer。req 是结构体,用指针可以节省内存,Writer 是一个接口类型,不能用指针。

Author: Mrli

Link: https://nymrli.top/2021/12/29/Go的进阶学习/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
使用七牛云作图床+PicGo
NextPost >
开发方向-技术栈
CATALOG
  1. 1. GO中通过组合方式实现的伪继承
  2. 2. 函数形参问题