方法

方法 其实就是一个函数,在 func 这个关键字和方法名中间加入了一个特殊的接收器类型。接收器可以是结构体类型或者是非结构体类型。接收器是可以在方法的内部访问的。

方法基础应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

type myInt int

func (a myInt) add(b myInt) myInt {
return a + b
}

func main() {
var x myInt = 50
var y myInt = 7
fmt.Println(x.add(y)) // 57
}

方法在结构体上应用

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
package main

import "fmt"

type Student struct {
name string // 学生姓名
sno string // 学生学号
}

type Teacher struct {
name string // 教师姓名
gz int //教师工资
}

func (stu Student) show() {
fmt.Println(stu.name)
fmt.Println(stu.sno)
}

func (th Teacher) show() {
fmt.Println(th.name)
fmt.Println(th.gz)
}

func main() {
stu := Student{"jpc", "123456"}
th := Teacher{"xhr", 12000}
stu.show()
th.show()
}

接口

Go 语言不是一种 “传统” 的面向对象编程语言:它里面没有类和继承的概念,

Go 语言里有非常灵活的 接口 概念,通过它可以实现很多面向对象的特性\, 接口提供了一种方式来说明对象的行为\,

  • 接口定义了一组方法(方法集),但是这些方法不包含(实现)代码。
  • 接口方法没有被实现(它们是抽象的)。
  • 接口里也不能包含变量。

接口隐式实现

隐式实现了 People 接口,实现的内容是打印语句。

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
package main

import "fmt"

type People interface {
fun()
}

type Student struct {
name string
age int
}

func (stu Student) fun() {
fmt.Println(stu.name, stu.age)
}

func main() {
stu := Student{
name: "jpc",
age: 21,
}
stu.fun()
}

接口实现多态

利用的接口实现了不同的功能,这就是多态。

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
package main

import "fmt"

type People interface {
fun()
}

type Student struct {
name string
age int
}

type Teacher struct {
name string
gz int
}

func (stu Student) fun() {
fmt.Println(stu.name, stu.age)
}

func (th Teacher) fun() {
fmt.Println(th.name, th.gz)
}

func main() {
stu := Student{
name: "jpc",
age: 21,
}
th := Teacher{
name: "xhr",
gz: 10010,
}
stu.fun()
th.fun()
}

空接口

空接口 是特殊形式的接口类型,没有定义任何方法的接口就称为空接口,可以说所有类型都至少实现了空接口,空接口表示为 interface{} 。例如,我们之前的写过的空接口参数函数,可以接受任何类型的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func ShowType(i interface{}) {
fmt.Printf("类型: %T, 值: %v\n", i, i)
}

func main() {
str := "11111"
ShowType(str)
num := 3.14
ShowType(num)
}

上面的程序中我们定义了函数 ShowType 使用空接口作为参数,所以可以给这个函数传递任何类型的参数。

直接使用 interface{} 作为类型声明一个实例,这个实例就能承载任何类型的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func main() {
var i interface{}

i = "111111"
fmt.Println(i)
i = 3.14
fmt.Println(i)
}

我们也可以定义一个接收任何类型的 arrayslicemapstrcut 。例如:

当空接口承载数组和切片后,该对象无法再进行切片。

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
a := make([]interface{}, 4, 5)
a[0] = "dsa1"
a[1] = 21
a[2] = []int{21, 231}
fmt.Println(a)
}

类型断言

类型断言用于提取接口的底层值(Underlying Value)。使用 interface.(Type) 可以获取接口的底层值,其中接口 interface 的具体类型是 Type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func assert(i interface{}) {
value, ok := i.(int)
fmt.Println(value, ok)
}

func main() {
var x interface{} = 3
assert(x)
var y interface{} = "abcd"
assert(y)
}