博客 / 詳情

返回

Go中的面向對象2 我算是徹底玩明白了

大傢伙,我是Mandy。

上一篇,我們分享了在Go中是如何實現面向對象,文章中對面向對象的三大特性中的繼承、封裝,做了一個理論和實踐的總結,這一篇繼續分享關於另外一個特性,那就是多態。

認識多態

老規矩,在代碼實踐之前,先對基礎知識做一個普及。

1、面向對象中的多態(Polymorphism)是指一個對象可以具有多種不同的形態或表現方式。簡單來説,就是同一個類型的對象,在不同的上下文中表現出不同的行為。多態性是面向對象的三大特性之一(封裝、繼承、多態)。

2、在多態中,父類的引用可以指向子類的對象,通過父類的引用調用子類的方法。這樣可以實現代碼的靈活性和擴展性,可以根據具體的對象類型調用相應的方法,無需關心對象的具體類型。

3、通過多態性,可以通過統一的接口來處理不同的對象,實現代碼的簡潔性和可維護性。多態性提供了一種抽象的方式來處理對象的不同行為,使得代碼更具靈活性和可擴展性。

總結一句,就是同一個方法在不同的對象實例中,可以有不同的行為。這裏簡單用PHP舉一個案例。

在PHP中實現多態需要遵循以下幾個步驟:

1、創建父類(基類):定義一個包含通用方法和屬性的父類。

class Animal {
  public function makeSound() {
    echo "Animal makes sound.";
  }
}

2、創建子類(派生類):繼承父類,並添加自己特定的方法和屬性。

class Dog extends Animal {
  public function makeSound() {
    echo "Dog barks.";
  }
}

class Cat extends Animal {
  public function makeSound() {
    echo "Cat meows.";
  }
}

3、創建對象並調用方法:通過父類的引用來實例化子類對象,可以根據具體的對象類型調用相應的方法。

$animal1 = new Dog();
$animal1->makeSound(); // Output: Dog barks.

$animal2 = new Cat();
$animal2->makeSound(); // Output: Cat meows.

通過以上步驟,我們可以實現多態性,即相同父類類型的對象(例如Animal),在不同的對象實例下調用相應的子類方法(例如Dog或Cat)。這樣就實現了多態的效果。

Go語言實現

因為Go中沒有面向對象的概念,但根據多態的定義和特點,我們可以使用Go中的interface來實現多態。

package main

import "fmt"

type Animal interface {
    run()
}

type Turtle struct {
}

func (t Turtle) run() {
    fmt.Println("烏龜爬行很慢")
}

type Rabbit struct {
}

func (r Rabbit) run() {
    fmt.Println("兔子跑步很快")
}

func main() {
    var animal Animal
    // 實例化一個Turtle對象
    animal = &Turtle{}
    animal.run()

    // 實例化一個Rabbit對象
    animal = &Rabbit{}
    animal.run()
}

1、首先我們定義了一個Animal的接口,並在接口中定義了一個約束,就是run()方法。

2、接着我們定義了Turtle和Rabbit兩個結構體,並分別定義了一個run()方法。

3、此時兩個結構體隱式的實現了Animal接口中的方法。

4、根據多態的特性,兩個結構體中的方法,都可以具備自己的行為。我們在兩個方法中分別打印了內容,此時能夠打印出不同的內容。不同的內容就可以理解為不同的行為,當然你也可以在這個方法中做其他的操作。

5、在main()方法中,創建一個Animal的變量,並通過不同的結構體實例,調用相同的方法名,最終輸出不同的內容。

實戰案例

上面對多態有了一定的瞭解,接着列舉一個實戰的案例。

在系統支付,一般我們會對接微信和支付寶這樣的平台,大致的流程就是,創建訂單記錄->組裝支付參數->發起支付請求->支付平台進行回調通知->修改訂單支付狀態。

基於這樣的邏輯,我們使用一個Pay接口,定義三個方法。

type Pay interface {
    createOrder() // 創建訂單
    createPay()   // 常見支付參數
    notifyPay()   // 回調通知
}

接着定義具體的實現類,就是微信支付和支付寶支付。

1、定義一個微信支付,用來實現接口中的三個方法。

type WeChat struct {
    // 微信支付方式
}

func (a WeChat) createOrder() {
    fmt.Println("我是微信支付,現在我正在創建訂單數據,用於記錄到數據庫中。")
}

func (a WeChat) createPay() {
    fmt.Println("我是微信支付,現在我正在創建支付數據,用於向微信發起支付請求使用。")
}

func (a WeChat) notifyPay() {
    fmt.Println("我是微信支付,現在我正在接受微信通知的參數,用於修改用户訂單支付狀態。")
}

2、定義一個支付寶支付,用來實現接口中的三個方法。

type Ali struct {
    // 支付寶支付方式
}

func (a Ali) createOrder() {
    fmt.Println("我是支付寶支付,現在我正在創建訂單數據,用於記錄到數據庫中。")
}

func (a Ali) createPay() {
    fmt.Println("我是支付寶支付,現在我正在創建支付數據,用於向支付寶發起支付請求使用。")
}

func (a Ali) notifyPay() {
    fmt.Println("我是支付寶支付,現在我正在接受支付寶通知的參數,用於修改用户訂單支付狀態。")
}

接下來,就來進行實際的訂單操作。

1、假設當前的支付渠道使用的是微信支付。

func main() {
    var pay Pay
    pay = &WeChat{}
    pay.createOrder()
    pay.createPay()
    pay.notifyPay()
}

最終輸出的結果為:

我是微信支付,現在我正在創建訂單數據,用於記錄到數據庫中。
我是微信支付,現在我正在創建支付數據,用於向微信發起支付請求使用。
我是微信支付,現在我正在接受微信通知的參數,用於修改用户訂單支付狀態。

2、假設當前的支付渠道使用的是支付寶支付。

func main() {
    var pay Pay
    pay = &Ali{}
    pay.createOrder()
    pay.createPay()
    pay.notifyPay()
}

最終輸出結果為:

我是支付寶支付,現在我正在創建訂單數據,用於記錄到數據庫中。
我是支付寶支付,現在我正在創建支付數據,用於向支付寶發起支付請求使用。
我是支付寶支付,現在我正在接受支付寶通知的參數,用於修改用户訂單支付狀態。

到此,在Go中實現面向對象以及三大特性(封裝、繼承和多態)就給大家分享完畢。

user avatar cyningsun 頭像 gouguoyin 頭像 stillfox 頭像
3 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.