Go | 定義介面並且結構實現
💬 簡介
在 Go 語言中,介面是實現多型的基礎,能夠讓不同的資料型別執行相同的操作。定義介面並且通過結構來實現它,是 Go 語言中非常重要的技巧,這使得程式具有更好的擴展性和可維護性。本文將詳細介紹如何定義介面並且通過結構來實現這些介面,並通過範例展示這一過程。
圖片來源:Gophers
🔍 定義介面
在 Go 語言中,介面是一種包含方法簽名的型別,它並不包含具體的實作,而是定義了一組方法。任何一個型別只要實現了介面中所有的方法,該型別就會自動實現該介面。這與 Java 和 C# 的顯式實現介面有所不同,Go 語言的介面實現是隱式的。
介面的語法
1 | type Speaker interface { |
📝 在這個例子中,我們定義了一個名為
Speaker
的介面,這個介面有一個方法Speak
,它會返回一個字串。
🛠 結構實現介面
結構可以通過實現介面中的所有方法來實現這個介面。在 Go 語言中,結構不需要顯式宣告它實現了某個介面,只需要實現介面所需的方法即可。
1️⃣ 結構實現單一介面
- 範例:
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
27package main
import "fmt"
// 定義 Speaker 介面
type Speaker interface {
Speak() string
}
// 定義 Person 結構
type Person struct {
Name string
}
// 為 Person 結構實現 Speak 方法
func (p Person) Speak() string {
return "Hello, my name is " + p.Name
}
func main() {
// 建立一個 Person 實例
p := Person{Name: "John"}
// 呼叫 Speak 方法
var s Speaker = p
fmt.Println(s.Speak()) // 輸出: Hello, my name is John
}📝 在這個範例中,我們定義了
Speaker
介面和Person
結構,並且為Person
結構實現了Speak
方法。然後我們建立了一個Person
實例,並將它賦值給Speaker
介面的變數s
。最終,通過介面的Speak
方法,輸出了Person
的名字。
在 Go 語言中,一個結構可以實現多個介面。這樣可以讓結構具備多種行為,這對於開發中常見的多型操作非常有用。
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
41package main
import "fmt"
// 定義 Speaker 介面
type Speaker interface {
Speak() string
}
// 定義 Walker 介面
type Walker interface {
Walk() string
}
// 定義 Person 結構
type Person struct {
Name string
}
// 為 Person 結構實現 Speak 方法
func (p Person) Speak() string {
return "Hello, my name is " + p.Name
}
// 為 Person 結構實現 Walk 方法
func (p Person) Walk() string {
return p.Name + " is walking."
}
func main() {
// 建立一個 Person 實例
p := Person{Name: "Alice"}
// 使用 Speaker 介面
var s Speaker = p
fmt.Println(s.Speak()) // 輸出: Hello, my name is Alice
// 使用 Walker 介面
var w Walker = p
fmt.Println(w.Walk()) // 輸出: Alice is walking.
}📝 在這個範例中,
Person
結構同時實現了Speaker
和Walker
兩個介面,這使得Person
結構具有了說話和行走的功能。這種設計在開發中非常有用,因為一個結構可以具有多種行為。
3️⃣ 動態處理不同的行為
介面可以讓你設計更加靈活和可擴展的程式,特別是當程式需要處理多種不同型別的資料時。使用介面來實現動態行為是 Go 語言中非常常見的一種做法。
- 範例:
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
43package main
import "fmt"
// 定義 Speaker 介面
type Speaker interface {
Speak() string
}
// 定義 Animal 結構
type Animal struct {
Species string
}
// 為 Animal 結構實現 Speak 方法
func (a Animal) Speak() string {
return "I am a " + a.Species
}
// 定義 Robot 結構
type Robot struct {
Model string
}
// 為 Robot 結構實現 Speak 方法
func (r Robot) Speak() string {
return "I am a robot model " + r.Model
}
// 定義一個函式,接受 Speaker 介面的參數
func introduce(speaker Speaker) {
fmt.Println(speaker.Speak())
}
func main() {
// 建立 Animal 和 Robot 實例
a := Animal{Species: "Dog"}
r := Robot{Model: "XJ-9"}
// 使用介面實現多型
introduce(a) // 輸出: I am a Dog
introduce(r) // 輸出: I am a robot model XJ-9
}📝 在這個範例中,
introduce
函式接受一個Speaker
介面作為參數,這意味著我們可以傳入任何實現了Speak
方法的結構。無論是Animal
還是Robot
,都可以通過這個統一的介面進行操作,這樣的設計增加了程式的靈活性和可擴展性。
4️⃣ 實現多個方法的複雜介面
這裡將展示一個需要實現多個方法的介面範例,這些方法涉及更多的行為。
- 範例:
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
65package main
import "fmt"
// 定義 Animal 介面,包含多個方法
type Animal interface {
Speak() string
Move() string
Eat() string
}
// 定義 Dog 結構
type Dog struct {
Name string
}
// 為 Dog 結構實現 Animal 介面中的所有方法
func (d Dog) Speak() string {
return "Woof! My name is " + d.Name
}
func (d Dog) Move() string {
return d.Name + " is running."
}
func (d Dog) Eat() string {
return d.Name + " is eating."
}
// 定義 Cat 結構
type Cat struct {
Name string
}
// 為 Cat 結構實現 Animal 介面中的所有方法
func (c Cat) Speak() string {
return "Meow! My name is " + c.Name
}
func (c Cat) Move() string {
return c.Name + " is jumping."
}
func (c Cat) Eat() string {
return c.Name + " is eating."
}
func main() {
// 建立 Dog 和 Cat 實例
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
// 使用 Animal 介面,呼叫不同的方法
var a Animal
a = dog
fmt.Println(a.Speak()) // 輸出: Woof! My name is Buddy
fmt.Println(a.Move()) // 輸出: Buddy is running.
fmt.Println(a.Eat()) // 輸出: Buddy is eating.
a = cat
fmt.Println(a.Speak()) // 輸出: Meow! My name is Whiskers
fmt.Println(a.Move()) // 輸出: Whiskers is jumping.
fmt.Println(a.Eat()) // 輸出: Whiskers is eating.
}📝 在這個範例中,我們定義了一個
Animal
介面,它包含了Speak
、Move
和Eat
三個方法。Dog
和Cat
結構都實現了這些方法,因此它們都能被賦值給Animal
介面的變數a
,並可以通過介面來呼叫它們的行為。
🎯 總結
在 Go 語言中,介面是實現多型和擴展性的強大工具。通過定義介面並實現它,結構能夠擁有通用的操作方式,從而提高程式碼的可擴展性和維護性。理解並掌握介面的使用,將有助於在 Go 開發中編寫更加靈活且高效的程式碼。
最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。
註:以上參考了
Go