自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 后端
在今天這篇文章中,我們介紹了常說的類和繼承的業(yè)內(nèi)定義和使用案例。同時(shí)面向 Go 讀者群里的疑惑,進(jìn)行了解答。實(shí)質(zhì)上,Go 是 OOP,也不是 OOP。類和繼承只是實(shí)現(xiàn) OOP 的一種方式,但并不是沒有這兩者,他就不是 OOP 了。

[[439475]]

本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚了」,作者陳煎魚。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚了公眾號(hào)。

大家好,我是煎魚。

大家在早期學(xué)習(xí) Go 時(shí),一旦跨過語法的階段后。馬上就會(huì)進(jìn)入到一個(gè)新的糾結(jié)點(diǎn),Go 不支持面向?qū)ο髥?

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

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

類和繼承

類是什么

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

例子如下:

  1. class SimpleClass 
  2.     // 聲明屬性 
  3.     public $var = '腦子進(jìn)煎魚了'
  4.  
  5.     // 聲明方法 
  6.     public function displayVar() { 
  7.         echo $this->var; 
  8.     } 

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

繼承是什么

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

例子如下:

  1. // 父類 
  2. class Foo 
  3.     public function printItem($string) 
  4.     { 
  5.         echo '煎魚1: ' . $string . PHP_EOL; 
  6.     } 
  7.      
  8.     public function printPHP() 
  9.     { 
  10.         echo 'PHP is great.' . PHP_EOL; 
  11.     } 
  12.  
  13. // 子類 
  14. class Bar extends Foo 
  15.     public function printItem($string) 
  16.     { 
  17.         echo '煎魚2: ' . $string . PHP_EOL; 
  18.     } 

繼承有如下兩個(gè)特性:

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

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

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

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

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

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

例子如下:

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type person struct { 
  6.     name string 
  7.     age  int 
  8.  
  9. func(p *person) hello(){} 
  10.  
  11. func newPerson(name string) *person { 
  12.     p := person{namename
  13.     p.age = 42 
  14.     return &p 
  15.  
  16. func main() { 
  17.     fmt.Println(person{"煎魚1", 22}) 
  18.     fmt.Println(person{name"煎魚2", age: 33}) 
  19.     ... 

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

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

組合

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

例子如下:

  1. type man struct { 
  2.  name string 
  3.  
  4. func (m *man) hello1() {} 
  5.  
  6. type person struct { 
  7.  man 
  8.  name string 
  9.  
  10. func (p *person) hello2() {} 
  11.  
  12. func newPerson(name string) *person { 
  13.  p := person{namename
  14.  return &p 
  15.  
  16. func main() { 
  17.  p := newPerson("腦子進(jìn)煎魚了"
  18.  p.hello1() 

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

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

在簡(jiǎn)單的使用效果上會(huì)與繼承有些接近。

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

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

是的,也不是。原因是:

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

為什么不支持類和繼承

有的人認(rèn)為類和繼承是面向?qū)ο蟮谋匾匦?,必須要有,才能是面向?qū)ο蟮恼Z言,但其實(shí)也并非如此。

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

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

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

總結(jié)

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

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

 

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

 

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2021-10-27 07:15:36

Go 循環(huán)引用

2021-11-08 11:02:01

Go函數(shù)重載

2021-12-15 07:49:22

Go語言設(shè)計(jì)

2023-01-28 08:05:32

轉(zhuǎn)換Go泛型

2024-01-01 08:10:40

Go語言map

2024-05-28 08:55:52

2024-01-05 08:45:35

Go語言map

2023-02-26 23:36:08

PHPGo函數(shù)

2020-07-22 08:01:41

Python開發(fā)運(yùn)算符

2020-10-09 06:48:19

Pythonswitch語句

2024-03-08 08:51:59

Gomain函數(shù)

2024-03-12 09:13:28

Go語言main

2023-04-03 11:21:29

PythonGoRust

2021-03-02 06:03:30

Java繼承對(duì)象

2023-03-07 21:43:29

Java多重繼承

2009-03-12 08:42:38

AndroidWMMTK

2021-08-02 09:31:20

Python工具代碼

2021-06-11 00:03:31

鴻蒙智能手機(jī)

2021-02-01 13:53:53

StringlongJava

2009-03-11 17:32:22

聯(lián)發(fā)科WMAndroid
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)