Like Share Discussion Bookmark Smile

J.J. Huang   2025-04-01   Getting Started Golang 06.介面   瀏覽次數:次   DMCA.com Protection Status

Go | 定義介面並且結構實現

💬 簡介

在 Go 語言中,介面是實現多型的基礎,能夠讓不同的資料型別執行相同的操作。定義介面並且通過結構來實現它,是 Go 語言中非常重要的技巧,這使得程式具有更好的擴展性和可維護性。本文將詳細介紹如何定義介面並且通過結構來實現這些介面,並通過範例展示這一過程。

圖片來源:Gophers


🔍 定義介面

在 Go 語言中,介面是一種包含方法簽名的型別,它並不包含具體的實作,而是定義了一組方法。任何一個型別只要實現了介面中所有的方法,該型別就會自動實現該介面。這與 Java 和 C# 的顯式實現介面有所不同,Go 語言的介面實現是隱式的。

介面的語法

1
2
3
type Speaker interface {
Speak() string
}

📝 在這個例子中,我們定義了一個名為 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
    27
    package 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
    41
    package 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 結構同時實現了 SpeakerWalker 兩個介面,這使得 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
    43
    package 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
    65
    package 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 介面,它包含了 SpeakMoveEat 三個方法。DogCat 結構都實現了這些方法,因此它們都能被賦值給 Animal 介面的變數 a,並可以通過介面來呼叫它們的行為。


🎯 總結

在 Go 語言中,介面是實現多型和擴展性的強大工具。通過定義介面並實現它,結構能夠擁有通用的操作方式,從而提高程式碼的可擴展性和維護性。理解並掌握介面的使用,將有助於在 Go 開發中編寫更加靈活且高效的程式碼。

最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。


註:以上參考了
Go