Go-Interface

关于 go 语言接口的简单介绍

接口对于 go 实现面向对象来说非常重要,如果没有它 go 的结构体(struct)也就只能存储一些信息,
但是相关的方法将会变得非常麻烦

什么是接口?

接口就是制定一个通用的规范,只要符合这个规范就能使用这个借口(听起来像是车轱辘话)

接口类型

比如我定义了一个接口

1
2
3
4
type example interface{
a()
b()
}

他定义了两个方法,只要有结构体中含有 a(),b()两个方法就能实现这个接口,通过接口来统一调用,
如下

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//package main
//import "fmt"

//定义一个基本的类
type Human struct{
name string
age int
phone string
}

type Student struct{
Human //继承 human 中的字段
school string
loan float32
}

type Employee struct{
Human
company string
money float32
}

//Human 实现 Sayhi 方法
func (h Human) Sayhi(){
fmt.Printf("hi my name is %s and my phone is %s \n", h.name,h.phone)
}

//Human 实现 Sing 方法
func (h Human) Sing(lyrics string) {
fmt.Println("galigaygay galigaygay ...",lyrics)
}

//student 复写 Sayhi 方法
func (sdt Student) Sayhi() {
fmt.Printf("my name is %s and my school is %s \n", sdt.name,sdt.school)
}

//定义一个通用的接口
type Men interface{
Sayhi()
Sing(lyrics string)
}

func main () {
//实例化两种类
mike := Student{Human{"mike",25,"18333636999"},"MIT",3.14}
jack := Employee{Human{"jack",30,"18333636998"},"hotcast",20000}

//定义一个接口变量
var i Men

//接口实现了 Student 类的方法
fmt.Println("下面有请 mike 开始他的表演:")
i = mike
i.Sayhi();
i.Sing("dongci daci")


//接口实现了 Employee 类的方法
fmt.Println("下面有请 mike 开始他的表演:")
i = jack
i.Sayhi();
i.Sing("haha haha haha")
}

这里的 Men 接口被所有继承了Human的结构体的方法所实现,所以这些实例化的结构体可以赋值给
Men的接口变量上,我们在 go 语言中的面向对象开发可以说就是面向接口在开发,由接口来组成一个个的
变量,
这和 php 的接口有所不同,在 php 中,接口是需要被 class 来继承,然后class 中去实现 interface 中
指定的方法,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
interface Human{
function sayHi();
function sing();
}

class Student implements Human{
public function sayHi(){
// TODO:
}
public function sing(){
// TODO:
}
}

这样子的, 每个类需要指定继承哪些接口才可以去实现接口,而 go 和 php 正好相反,是谁实现了我的规范
谁就可以用我的接口,实现顺序正好倒过来了

再举一个接口的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
"fmt"
"strconv"
)

type Human struct {
name string
age int
phone string
}

// 这里需要把 int 类型转换成字符串,否则使用 + 来连接字符的时候报数据类型不匹配的错误
func (h Human) String() string {
return "<" + h.name + "-" + strconv.Itoa(h.age) + "years old ,phone is " + h.phone + "/>"
}

func main() {
Duck := Human{"duck", 22, "110-120-119"}
fmt.Println("this human is :", Duck)
}

上述例子当中我们实现了 fmt.Println 中的一个接口
`go
type Stringer interface {
String() string
}

这样之后,调用 Human 的 String() 函数就能被 fmt.Println() 所用了