5.4.4 多态

现在了解了接口和方法集背后的机制,最后来看一个展示接口的多态行为的例子,如代码清单5-48所示。

代码清单5-48 listing48.go

01 // 这个示例程序使用接口展示多态行为
02 package main
03
04 import (
05   "fmt"
06 )
07
08 // notifier是一个定义了
09 // 通知类行为的接口
10 type notifier interface {
11   notify()
12 }
13
14 // user在程序里定义一个用户类型
15 type user struct {
16   name string
17   email string
18 }
19
20 // notify使用指针接收者实现了notifier接口
21 func (u *user) notify() {
22   fmt.Printf("Sending user email to %s<%s>\n",
23     u.name,
24     u.email)
25 }
26
27 // admin定义了程序里的管理员
28 type admin struct {
29   name string
30   email string
31 }
32
33 // notify使用指针接收者实现了notifier接口
34 func (a *admin) notify() {
35   fmt.Printf("Sending admin email to %s<%s>\n",
36     a.name,
37     a.email)
38 }
39
40 // main是应用程序的入口
41 func main() {
42   // 创建一个user值并传给sendNotification
43   bill := user{"Bill", "bill@email.com"}
44   sendNotification(&bill)
45
46   // 创建一个admin值并传给sendNotification
47   lisa := admin{"Lisa", "lisa@email.com"}
48   sendNotification(&lisa)
49 }
50
51 // sendNotification接受一个实现了notifier接口的值
52 // 并发送通知
53 func sendNotification(n notifier) {
54   n.notify()
55 }

在代码清单5-48中,我们有了一个展示接口的多态行为的例子。在第10行,我们声明了和之前代码清单中一样的 notifier 接口。之后第15行到第25行,我们声明了一个名为 user 的结构,并使用指针接收者实现了 notifier 接口。在第28行到第38行,我们声明了一个名为 admin 的结构,用同样的形式实现了 notifier 接口。现在,有两个实体类型实现了 notifier 接口。

在第53行中,我们再次声明了多态函数 sendNotification ,这个函数接收一个实现了 notifier 接口的值作为参数。既然任意一个实体类型都能实现该接口,那么这个函数可以针对任意实体类型的值来执行 notifier 方法。因此,这个函数就能提供多态的行为,如代码清单5-49所示。

代码清单5-49 listing48.go:第40行到第49行

40 // main是应用程序的入口
41 func main() {
42   // 创建一个user值并传给sendNotification
43   bill := user{"Bill", "bill@email.com"}
44   sendNotification(&bill)
45
46   // 创建一个admin值并传给sendNotification
47   lisa := admin{"Lisa", "lisa@email.com"}
48   sendNotification(&lisa)
49 }

最后,可以在代码清单5-49中看到这种多态的行为。 main 函数的第43行创建了一个 user 类型的值,并在第44行将该值的地址传给了 sendNotification 函数。这最终会导致执行 user 类型声明的 notify 方法。之后,在第47行和第48行,我们对 admin 类型的值做了同样的事情。最终,因为 sendNotification 接收 notifier 类型的接口值,所以这个函数可以同时执行 useradmin 实现的行为。

results matching ""

    No results matching ""