Golang 中的面向?qū)ο?/h2>
image

前言

我的讀者中應(yīng)該大部分都是 Java 從業(yè)者,不知道寫 Java 這些年是否真的有找到對(duì)象?

沒找到也沒關(guān)系,總不能在一棵樹上吊死,我們也可以來 Go 這邊看看,說不定會(huì)有新發(fā)現(xiàn)。

開個(gè)玩笑,本文會(huì)以一個(gè) Javaer 的角度來聊聊 Go 語言中的面向?qū)ο蟆?/p>

OOP

面向?qū)ο筮@一詞來源于Object Oriented Programming,也就是大家常說的 OOP。

對(duì)于 Go 是否為面向?qū)ο蟮木幊陶Z言,這點(diǎn)也是討論已久;不過我們可以先看看官方的說法:

image

其他的我們暫且不看,Yes and No. 這個(gè)回答就比較微妙了,為了這篇文章還能寫下去我們先認(rèn)為 Go 是面向?qū)ο蟮摹?/p>


面向?qū)ο笥兄齻€(gè)重要特征:

  1. 封裝
  2. 繼承
  3. 多態(tài)

封裝

Go 并沒有 Class 的概念,卻可以使用 struct 來達(dá)到類似的效果,比如我們可以對(duì)汽車聲明如下:

type Car struct {
    Name string
    Price float32
}

Java 不同的是,struct 中只存儲(chǔ)數(shù)據(jù),不能定義行為,也就是方法。

當(dāng)然也能為 Car 定義方法,只是寫法略有不同:

func (car *Car) Info()  {
    fmt.Printf("%v price: [%v]", car.Name, car.Price)
}

func main() {
    car := Car{
        Name: "BMW",
        Price: 100.0,
    }
    car.Info()

}

在方法名稱前加上 (car *Car) 便能將該方法指定給 Car ,其中的 car 參數(shù)可以理解為 Java 中的 this 以及 Python 中的 self,就語義來說我覺得 go 更加簡單一些。

畢竟我見過不少剛學(xué)習(xí) Java 的萌新非常不理解 this 的含義與用法。

匿名結(jié)構(gòu)體

既然談到結(jié)構(gòu)體了那就不得不聊聊 Go 支持的匿名結(jié)構(gòu)體(雖然和面向?qū)ο鬀]有太大關(guān)系)

func upload(path string) {
    body, err := ioutil.ReadAll(res.Body)
    smsRes := struct {
        Success bool   `json:"success"`
        Code    string `json:"code"`
        Message string `json:"message"`
        Data    struct {
            URL string `json:"url"`
        } `json:"data"`
        RequestID string `json:"RequestId"`
    }{}
    err = json.Unmarshal(body, &smsRes)
    fmt.Printf(smsRes.Message)
}

Go 允許我們?cè)诜椒▋?nèi)部創(chuàng)建一個(gè)匿名的結(jié)構(gòu)體,后續(xù)還能直接使用該結(jié)構(gòu)體來獲取數(shù)據(jù)。

這點(diǎn)在我們調(diào)用外部接口解析響應(yīng)數(shù)據(jù)時(shí)非常有用,創(chuàng)建一個(gè)臨時(shí)的結(jié)構(gòu)體也不用額為維護(hù);同時(shí)還能用面向?qū)ο蟮姆绞将@取數(shù)據(jù)。

相比于將數(shù)據(jù)存放在 map 中用字段名獲取要優(yōu)雅許多。

繼承

Go 語言中并沒有 Java、C++ 這樣的繼承概念,類之間的關(guān)系更加扁平簡潔。

各位 Javaer 應(yīng)該都看過這類圖:

image

相信大部分新手看到這圖時(shí)就已經(jīng)懵逼,更別說研究各個(gè)類之間的關(guān)系了。

不過這樣好處也明顯:如果我們抽象合理,整個(gè)系統(tǒng)結(jié)構(gòu)會(huì)很好維護(hù)和擴(kuò)展;但前提是我們能抽象合理。

Go 語言中更推薦使用組合的方式來復(fù)用數(shù)據(jù):

type ElectricCar struct {
    Car
    Battery int32
}

func main() {
    xp := ElectricCar{
        Car{Name: "xp", Price: 200},
        70,
    }
    fmt.Println(xp.Name)

}

這樣我們便可以將公共部分的數(shù)據(jù)組合到新的 struct 中,并能夠直接使用。

接口(多態(tài))

面向接口編程的好處這里就不在贅述了,我們來看看 Go 是如何實(shí)現(xiàn)的:

type ElectricCar struct {
    Car
    Battery int32
}
type PetrolCar struct {
    Car
    Gasoline int32
}

//定義一個(gè)接口
type RunService interface {
    Run()
}

// 實(shí)現(xiàn)1
func (car *PetrolCar) Run() {
    fmt.Printf("%s PetrolCar run \n", car.Name)
}

// 實(shí)現(xiàn)2
func (car *ElectricCar)Run() {
    fmt.Printf("%s ElectricCar run \n", car.Name)
}

func Do(run RunService) {
    run.Run()
}

func main() {
    xp := ElectricCar{
        Car{Name: "xp", Price: 200},
        70,
    }
    petrolCar := PetrolCar{
        Car{Name: "BMW", Price: 300},
        50,
    }
    Do(&xp)
    Do(&petrolCar)

}

首先定義了一個(gè)接口 RunService;ElectricCarPetrolCar 都實(shí)現(xiàn)了該接口。

可以看到 Go 實(shí)現(xiàn)一個(gè)接口的方式并不是 implement,而是用結(jié)構(gòu)體聲明一個(gè)相同簽名的方法。

這種實(shí)現(xiàn)模式被稱為”鴨子類型“,Python 中的接口也是類似的鴨子類型。

image

詳細(xì)介紹可以參考這篇:Python 中的面向接口編程

接口當(dāng)然也是可以擴(kuò)展的,類似于 struct 中的嵌套:

type DiService interface {
    Di()
}

//定義一個(gè)接口
type RunService interface {
    DiService
    Run()
}
image

得益于 Go 的強(qiáng)類型,剛才的 struct 也得實(shí)現(xiàn) DiService 這個(gè)接口才能編譯通過。

總結(jié)

到這里應(yīng)該是能理解官方所說的 Yes and No. 的含義了;Go 對(duì)面向?qū)ο蟮恼Z法不像 Java 那么嚴(yán)苛,甚至整個(gè)語言中都找不到 object(對(duì)象) 這個(gè)關(guān)鍵詞;但是利用 Go 里的其他特性也是能實(shí)現(xiàn) OOP 的。

是否為面向?qū)ο笪矣X得并不重要,主要目的是我們能寫出易擴(kuò)展好維護(hù)的代碼。

例如官方標(biāo)準(zhǔn)庫中就有許多利用接口編程的例子:

image

由于公司技術(shù)?,F(xiàn)在主要由 Go 為主,后續(xù)也會(huì)繼續(xù)更新 Go 相關(guān)的實(shí)戰(zhàn)經(jīng)驗(yàn);如果你也對(duì)學(xué)習(xí) Go 感興趣那不妨點(diǎn)個(gè)關(guān)注吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容