1. 程式人生 > >golang語言漸入佳境[18]-interface介面

golang語言漸入佳境[18]-interface介面

介面宣告與定義

interface關鍵字,在介面中有函式,但是沒有實現。

1
2
3
type Phone interface {
call()
}

例子

一旦有結構體實現了此函式,那麼就可以用介面來接收此結構體。

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

import "fmt"

type Phone interface {
call()
}

type AndroidPhone struct {
}

type IPhone struct
{

}

func (a AndroidPhone) call() {
fmt.Println("我是安卓手機,可以打電話了")
}

func (i IPhone) call() {
fmt.Println("我是蘋果手機,可以打電話了")
}

func main() {
// 定義介面型別的變數
var phone Phone
phone = new(AndroidPhone)
phone = AndroidPhone{}
fmt.Printf("%T , %v , %p \n" , phone , phone , &phone)
phone.call()

phone = new(IPhone)
phone = IPhone{}

fmt.Printf("%T , %v , %p \n" , phone , phone , &phone)
phone.call()
}

案例2

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main

import "fmt"

type Income interface {
calculate() float64
//計算收入總額

source() string     //用來說明收入來源
}

//固定賬單專案
type FixedBilling struct {
projectName  string  //工程專案
biddedAmount float64 //專案招標總額
}

//定時生產專案(定時和材料專案)
type TimeAndMaterial struct {
projectName string
workHours   float64 //工作時長
hourlyRate  float64 //每小時工資率
}

//固定收入專案
func (f FixedBilling) calculate() float64 {
return f.biddedAmount
}

func (f FixedBilling) source() string {
return f.projectName
}

//定時收入專案
func (t TimeAndMaterial) calculate() float64 {
return t.workHours * t.hourlyRate
}

func (t TimeAndMaterial) source() string {
return t.projectName
}

//通過廣告點選獲得收入
type Advertisement struct {
adName         string
clickCount     int
incomePerclick float64
}

func (a Advertisement) calculate() float64 {
return float64(a.clickCount) * a.incomePerclick
}

func (a Advertisement) source() string {
return a.adName
}

func main() {
p1 := FixedBilling{"專案1", 5000}
p2 := FixedBilling{"專案2", 10000}
p3 := TimeAndMaterial{"專案3", 100, 40}
p4 := TimeAndMaterial{"專案4", 250, 20}
p5 := Advertisement{"廣告1", 10000, 0.1}
p6 := Advertisement{"廣告2", 20000, 0.05}

ic := []Income{p1, p2, p3, p4, p5, p6}
fmt.Println(calculateNetIncome(ic))
}

//計算淨收入
func calculateNetIncome(ic []Income) float64 {
netincome := 0.0
for _, income := range ic {
fmt.Printf("收入來源:%s ,收入金額:%.2f \n", income.source(), income.calculate())
netincome += income.calculate()
}
return netincome
}

//說明:
// 沒有對calculateNetIncome函式做任何更改,儘管添加了新的收入方式。全靠多型性而起作用。
// 由於新的Advertisement型別也實現了Income介面,可以將它新增到ic切片中。
// calculateNetIncome函式在沒有任何更改的情況下工作,因為它可以呼叫Advertisement型別的calculate()和source()方法。

空介面

1
2
type A interface {
}

空介面可以接受任何的資料型別

1
2
3
4
5
6
7
type A interface {
}
var a1 A = Cat{"Mimi", 1}
var a2 A = Person{"Steven", "男"}
var a3 A = "Learn golang with me!"
var a4 A = 100
var a5 A = 3.14

定義map。value是任何資料型別

1
2
3
4
5
//2、定義map。value是任何資料型別
map1 := make(map[string]interface{})
map1["name"] = "Daniel"
map1["age"] = 13
map1["height"] = 1.71

定義一個切片,其中儲存任意資料型別

1
2
3
slice1 := make([]interface{}, 0, 10)
slice1 = append(slice1, a1, a2, a3, a4, a5)
fmt.Println(slice1)

完整案例

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

import (
"fmt"
)

type A interface {
}

type Cat struct {
name string
age  int
}

type Person struct {
name string
sex  string
}

func main() {
var a1 A = Cat{"Mimi", 1}
var a2 A = Person{"jonson", "男"}
var a3 A = "Learn golang with me!"
var a4 A = 100
var a5 A = 3.14

showInfo(a1)
showInfo(a2)
showInfo(a3)
showInfo(a4)
showInfo(a5)
fmt.Println("------------------")

//1、fmt.println引數就是空介面
fmt.Println("println的引數就是空介面,可以是任何資料型別", 100, <