<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 為什么不支持類和繼承?

          共 2781字,需瀏覽 6分鐘

           ·

          2021-12-27 08:33

          大家好,我是煎魚。

          大家在早期學習 Go 時,一旦跨過語法的階段后。馬上就會進入到一個新的糾結(jié)點,Go 不支持面向?qū)ο髥幔?/p>

          這門編程語言里沒有類(class)、繼承(extends),沒法一把搜了,面試問啥面向?qū)ο螅∣OP)?

          今天煎魚就帶大家一起來了解這之中的思考,Go 真的不支持嗎?

          類和繼承

          類是什么

          類(class)在面向?qū)ο缶幊讨惺且环N面向?qū)ο笥嬎銠C編程語言的構(gòu)造,是創(chuàng)建對象的藍圖,描述了所創(chuàng)建的對象共同的特性和方法(via @維基百科)。

          例子如下:

          class?SimpleClass
          {
          ????//?聲明屬性
          ????public?$var?=?'腦子進煎魚了';

          ????//?聲明方法
          ????public?function?displayVar()?{
          ????????echo?$this->var;
          ????}
          }

          每個類的定義都以關(guān)鍵字 class 開頭,后面跟著類名,后面跟著一對花括號,里面包含有類的屬性與方法的定義。

          繼承是什么

          繼承是面向?qū)ο筌浖夹g(shù)當中的一個概念,如果一個類別 B “繼承自”另一個類別 A,就把這個 B 稱為 “A的子類”,而把 A 稱為 “B的父類別” 也可以稱 “A 是 B 的超類”(via @維基百科)。

          例子如下:

          //?父類
          class?Foo
          {
          ????public?function?printItem($string)
          ????
          {
          ????????echo?'煎魚1:?'?.?$string?.?PHP_EOL;
          ????}
          ????
          ????public?function?printPHP()
          ????
          {
          ????????echo?'PHP?is?great.'?.?PHP_EOL;
          ????}
          }

          //?子類
          class?Bar?extends?Foo
          {
          ????public?function?printItem($string)
          ????
          {
          ????????echo?'煎魚2:?'?.?$string?.?PHP_EOL;
          ????}
          }

          繼承有如下兩個特性:

          • 子類具有父類別的各種屬性和方法,不需要再次編寫相同的代碼。
          • 子類別繼承父類時,可以重新定義某些屬性,并重寫某些方法,使其獲得與父類別不同的功能。

          結(jié)構(gòu)和組合

          在 Go 里就比較 ”特別“ 了,因為沒有傳統(tǒng)的類,也沒有繼承。

          取而代之的是結(jié)構(gòu)和組合的方式。這也是業(yè)內(nèi)對 Go 是否 OOP 爭議最大的地方。

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

          我們可以在 Go 中通過結(jié)構(gòu)體的方式來組織代碼,達到類似類的方式。

          例子如下:

          package?main

          import?"fmt"

          type?person?struct?{
          ????name?string
          ????age??int
          }

          func(p?*person)?hello(){}

          func?newPerson(name?string)?*person?{
          ????p?:=?person{name:?name}
          ????p.age?=?42
          ????return?&p
          }

          func?main()?{
          ????fmt.Println(person{"煎魚1",?22})
          ????fmt.Println(person{name:?"煎魚2",?age:?33})
          ????...
          }

          在上述代碼中,我們可以定義結(jié)構(gòu)體內(nèi)的屬性,也可以針對結(jié)構(gòu)體這些類型定義只屬于他們的方法。

          在聲明實例上,可以配合 newXXX 的初始化方法來生成,這是 Go 里約定俗成的方式。

          組合

          類的聲明采取結(jié)構(gòu)體的方式取代后,也可以配套使用 ”組合“ 來達到類似繼承的效果。

          例子如下:

          type?man?struct?{
          ?name?string
          }

          func?(m?*man)?hello1()?{}

          type?person?struct?{
          ?man
          ?name?string
          }

          func?(p?*person)?hello2()?{}

          func?newPerson(name?string)?*person?{
          ?p?:=?person{name:?name}
          ?return?&p
          }

          func?main()?{
          ?p?:=?newPerson("腦子進煎魚了")
          ?p.hello1()
          }

          在上述代碼中,我們分別定義了 man 和 person 兩個結(jié)構(gòu)體,并將 man 嵌入到 person 中,形成組合。

          你可以在 main 方法中能夠看到,person 實例是可以使用和調(diào)用 man 實例的一些公開屬性和方法的。

          在簡單的使用效果上會與繼承有些接近。

          Go 是面向?qū)ο蟮恼Z言嗎

          “Go 語言是否一門面向?qū)ο蟮恼Z言?”,這是一個日經(jīng)話題。官方 FAQ 給出的答復(fù)是:

          是的,也不是。原因是:

          • Go 有類型和方法,并且允許面向?qū)ο蟮木幊田L格,但沒有類型層次。
          • Go 中的 "接口 "概念提供了一種不同的方法,我們認為這種方法易于使用,而且在某些方面更加通用。還有一些方法可以將類型嵌入到其他類型中,以提供類似的東西,但不等同于子類。
          • Go 中的方法比 C++ 或 Java 中的方法更通用:它們可以為任何類型的數(shù)據(jù)定義,甚至是內(nèi)置類型,如普通的、"未裝箱的 "整數(shù)。它們并不局限于結(jié)構(gòu)(類)。
          • Go 由于缺乏類型層次,Go 中的 "對象 "比 C++ 或 Java 等語言更輕巧。

          為什么不支持類和繼承

          有的人認為類和繼承是面向?qū)ο蟮谋匾匦裕仨氁校拍苁敲嫦驅(qū)ο蟮恼Z言,但其實也并非如此。

          面向?qū)ο螅∣OP)有不同的含義和解讀,許多概念也可以通過結(jié)構(gòu)體、組合和接口等方式進行表達,說是不支持傳統(tǒng)的 OOP。

          其實真相是 Go 是選擇了另外一條路,也就是 ”組合優(yōu)于繼承“。我們所提到的類和繼承并不是定義 OOP 的一種準則,只是協(xié)助完成 OOP 的方法之一。

          不要本末倒置了,不讓工具來定義 OOP 的理念。

          總結(jié)

          在今天這篇文章中,我們介紹了常說的類和繼承的業(yè)內(nèi)定義和使用案例。同時面向 Go 讀者群里的疑惑,進行了解答。

          實質(zhì)上,Go 是 OOP,也不是 OOP。類和繼承只是實現(xiàn) OOP 的一種方式,但并不是沒有這兩者,他就不是 OOP 了。

          不支持的原因也很明確,Go 在設(shè)計上,選擇了組合優(yōu)于繼承的編程設(shè)計模式,它不是傳統(tǒng)那種面向類型的范式。

          你覺得呢,歡迎大家在評論區(qū)留言和交流:)


          關(guān)注煎魚,獲取最新的一手知識???


          你好,我是煎魚,出版過 Go 暢銷書《Go 語言編程之旅》,再到獲得 GOP(Go 領(lǐng)域最有觀點專家)榮譽,點擊藍字查看我的出書之路。

          日常分享高質(zhì)量文章,輸出 Go 面試、工作經(jīng)驗、架構(gòu)設(shè)計,加微信拉讀者交流群,和大家交流!

          瀏覽 78
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  爱视频国产在线 | 天天视频国产 | 影音先锋在线观看资源男人网 | 无码熟妇人妻AV在线电影 | 欧美日韩丁香五月天色网 |