亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

Golang中匿名組合實現偽繼承的方法

2020-04-01 18:53:47
字體:
來源:轉載
供稿:網友

"Go語言的面向對象機制與一般語言不同。 它沒有類層次結構, 甚至可以說沒有類; 僅僅通過組合( 而不是繼承) 簡單的對象來構建復雜的對象。" -- 《Go語言圣經》

1.匿名組合

1.1 匿名組合定義 

golang中組合語法,就是在一個類中,引入了另一個類,如

  type Logger struct{  }  type Work struct{    log Logger  }  type Work2 struct{    log *Logger  }  func (Logger)Info(v ...interface{}){  }

如上邊代碼所示,Work類中定義了一個Logger類型的變量,這種是比較常見的引入方式,姑且在此稱之為非匿名組合,那什么是匿名組合呢,如其名,就是在組合的過程中,不給名字唄,如代碼所示:

type Logger struct {}type Work struct {  Logger}type Work2 struct {  *Logger}func (Logger) Info(v ...interface{}) {}

上邊的代碼中,Work類與Work2類均與Logger類匿名組合。兩個類唯一不同的是,Work2中組合的是指針類型的Logger類。

1.2 組合對象初始化 

非匿名組合初始化方式

func main(){  var wk = Work{log:Logger{}}  var wwk = Work{Logger{}}  //...and so on  var wk2 = Work2{log:new(Logger)}  var wwk2 = Work2{new(Logger)}  //... and so on}

匿名組合初始化

func main(){  var wk = Work{Logger{}}  var wwk = Work{Logger:Logger{}}  //... and so on  var wk2 = Work2{new(Logger)}  var wwk2 = Work2{Logger:&Logger{}}  //... and so on}

上邊是匿名組合常見的初始化方式。匿名組合后,被包含類得方法和屬性可以直接被使用,即使是私有變量。 

注意事項: 

1.匿名組合多個類時,不同的類存在相同的方法,會不會沖突?答案是,不同的類中,不同的方法時不會沖突的,但是在調用這個方法時,需要明確是那個類中的方法,如果匿名組合進來的類得方法,與這個類主體中的方法發生沖突,那么默認情況下,會使用主體類中的方法。 

2.匿名組合多個類時,類名相同,會不會沖突?答案是,會。就算包名不同,類名相同,也會沖突。 

示例代碼:

package mainimport(  "bufio")type Reader struct {}type Work4 struct {  Reader  bufio.Reader}

上邊代碼編譯時,會提示Reader重復定義 duplicate field Reader 

原因在于,匿名組合中,沒有給引入的類命名,所以默認采用了類名作為屬性名。如上邊wwk2這個對象在調用Logger的Info方法時,可以采用wwk2.Info(“hello”),也可以采用wwk2.Logger.Info(“hello”). 

下邊附上一段完整的演示代碼,注意會報錯哦,這段代碼包含了上邊的duplicate field Reader錯誤:

package mainimport (  "bufio"  "fmt")type Logger struct {}type Work struct {  Logger}type Work2 struct {  *Logger}type Work3 struct {  log *Logger}type Reader struct {}type Work4 struct {  Reader  bufio.Reader}func (Logger) Info(v ...interface{}) {  fmt.Println(v...)}func main() {  var wk = Work{Logger{}}  wk.Info("hello: Work{Logger{}}")  var wwk = Work{Logger: Logger{}}  wwk.Info("hello: Work{Logger: Logger{}}")  //... and so on  var wk2 = Work2{new(Logger)}  wk2.Info("hello: Work2{new(Logger)}")  var wwk2 = Work2{Logger: &Logger{}}  wwk2.Info("hello: Work2{Logger: &Logger{}}")  wwk2.Logger.Info("hello: wwk2.Logger.Info")  var wk3 = Work3{new(Logger)}  wk3.log.Info("hello: Work3{new(Logger)}")}

3. 結構體嵌入和匿名成員

Go語言提供別樣的 結構體嵌入 機制,讓一個結構體包含另一個結構體類型的 匿名成員 , 這樣就可以通過簡單的點運算符x.f來訪問匿名成員鏈中嵌套的x.d.e.f成員。

Go語言有一個特性讓我們只聲明一個成員對應的數據類型而不指名成員的名字; 這類成員就叫匿名成員。 匿名成員的數據類型必須是命名的(而不是匿名的)類型或指向一個命名的類型的指針。

type Circle struct { Point Radius int} type Wheel struct { Circle Spokes int}

由于有了匿名嵌入的特性, 我們可以直接訪問內嵌類型的成員變量而不需要給出完整的路徑:

var w Wheelw.X = 8 // 等價于 w.Circle.Point.X = 8w.Y = 8 // 等價于 w.Circle.Point.Y = 8w.Radius = 5 // 等價于 w.Circle.Radius = 5w.Spokes = 20

同樣的規則,內嵌類型的方法也會提升為外部類型的方法。

3.1 匿名沖突(duplicate field)

匿名成員也有一個隱式的名字,以其類型名稱(去掉包名部分)作為成員變量的名字。 因此不能同一級同時包含兩個類型相同的匿名成員, 這會導致名字沖突。

type Logger struct {  Level int}type MyJob struct {  *Logger  Name string  *log.Logger // duplicate field Logger}

4. 匿名組合不是繼承

4.1 方法的接受者沒變

當我們嵌入一個類型,這個類型的方法就變成了外部類型的方法,但是當它被調用時,方法的接受者是內部類型(嵌入類型),而非外部類型。— Effective Go

type Job struct { Command string *log.Logger}func (job *Job)Start() { job.Log("starting now...") ... // 做一些事情 job.Log("started.")}

上面這個Job例子,即使組合后調用的方式變成了job.Log(...),但Log函數的接收者仍然是 log.Logger指針,因此在Log中也不可能訪問到job的其他成員方法和變量。

4.1 內嵌類型不是基類

如果讀者對基于 類 來實現的面向對象語言比較熟悉的話, 可能會傾向于將 內嵌類型 看作一個基類, 而 外部類型 看作其子類或者繼承類, 或者將 外部類型 看作 "is a" 內嵌類型 。 但這樣理解是錯誤的。

type Point struct{ X, Y float64 }type ColoredPoint struct { Point Color color.RGBA}func (p Point) Distance(q Point) float64 { dX := q.X - p.X dY := q.Y - p.Y return math.Sqrt(dX*dX + dY*dY)}

請注意上面例子中對Distance方法的調用。 Distance有一個參數是Point類型, 但q并不是一個Point類, 所以盡管q有著Point這個內嵌類型, 我們也必須要顯式地選擇它。 嘗試直接傳q的話你會看到錯誤:

red := color.RGBA{255, 0, 0, 255}blue := color.RGBA{0, 0, 255, 255}var p = ColoredPoint{Point{1, 1}, red}var q = ColoredPoint{Point{5, 4}, blue}fmt.Println(p.Distance(q.Point)) // "5"p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point

一個ColoredPoint并不是一個Point, 但ColoredPoint "has a" Point, 并且它有從Point類里引入的 Distance方法。

實際上,從實現的角度來考慮問題, 內嵌字段會指導編譯器去生成額外的包裝方法來委托已經聲明好的方法, 和下面的形式是等價的:

func (p ColoredPoint) Distance(q Point) float64 { return p.Point.Distance(q)}

當Point.Distance被以上編譯器生成的包裝方法調用時, 它的接收器值是p.Point, 而不是p。

4.3 匿名沖突(duplicate field) 和隱式名字

匿名成員也有一個隱式的名字,以其類型名稱(去掉包名部分)作為成員變量的名字。 因此不能同一級同時包含兩個類型相同的匿名成員, 這會導致名字沖突。

type Logger struct {Level int}type MyJob struct {*LoggerName string*log.Logger // duplicate field Logger}

以下兩點都間接說明匿名組合不是繼承:

  • 匿名成員有隱式的名字
  • 匿名可能沖突(duplicate field)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩欧美视频| 91产国在线观看动作片喷水| 亚洲精品97久久| 欧美精品第一页在线播放| 国产日韩欧美在线| 热re99久久精品国产66热| 7777精品视频| 国产97免费视| 欧美做爰性生交视频| 亚洲天堂2020| 日韩视频永久免费观看| 欧美国产极速在线| 国产亚洲视频中文字幕视频| 在线观看91久久久久久| 欧美亚洲午夜视频在线观看| 日韩欧美中文第一页| 欧洲成人在线观看| 欧美亚洲激情视频| 精品一区精品二区| 日韩中文视频免费在线观看| 久久久久久久一区二区| 久久久久久久久久久国产| 欧美午夜精品久久久久久久| 色偷偷av一区二区三区| 日韩免费观看高清| 亚洲一区二区日本| 日韩视频免费中文字幕| 国产精品欧美亚洲777777| 欧美日韩美女在线观看| 亚州av一区二区| 日韩欧美一区视频| 91免费在线视频网站| 国产精品免费视频久久久| 欧美性xxxx在线播放| 国产精品免费看久久久香蕉| 日韩精品www| 日本免费一区二区三区视频观看| 日韩在线一区二区三区免费视频| 欧美精品videofree1080p| 国产精品va在线播放我和闺蜜| 亚洲视频在线观看网站| 亚洲欧洲成视频免费观看| 久久久中文字幕| 97精品国产97久久久久久春色| 精品久久久久久久大神国产| 久久久久久久久久久国产| 国产精品一区二区三区在线播放| 亚洲性生活视频| 日韩在线视频观看正片免费网站| 久久久午夜视频| 色爱av美腿丝袜综合粉嫩av| 亚洲色图欧美制服丝袜另类第一页| 91久久精品国产91久久| 久久久国产91| 国产精品视频最多的网站| 国产一区二区三区在线看| 91九色国产视频| 91亚洲va在线va天堂va国| 日本一本a高清免费不卡| 97视频免费在线看| 亚洲人成电影网站色| 5566日本婷婷色中文字幕97| 亚洲欧洲xxxx| 成人网中文字幕| 色与欲影视天天看综合网| 亚洲欧美中文日韩在线| 中文字幕最新精品| 欧美日韩爱爱视频| 成人福利免费观看| 亚洲一区二区三区香蕉| 777国产偷窥盗摄精品视频| 欧美黄色片视频| 国产91色在线播放| 日韩电视剧在线观看免费网站| 亚洲国产日韩欧美在线99| 欧美日韩国产中文精品字幕自在自线| 国产日韩欧美自拍| 免费91麻豆精品国产自产在线观看| 成人做爽爽免费视频| 国产一区私人高清影院| 国产精品入口福利| 亚洲精品视频在线播放| 欧美日韩视频免费播放| 中文字幕精品国产| 亚洲精品www久久久久久广东| 在线电影欧美日韩一区二区私密| 欧美精品videosex极品1| 欧美大片免费观看在线观看网站推荐| 中文字幕精品一区二区精品| 欧美激情精品久久久久久变态| 成人亚洲欧美一区二区三区| 欧美精品在线极品| 亚洲国产精品免费| 欧美性猛交xxxx免费看久久久| 国产精品亚洲视频在线观看| 国产亚洲日本欧美韩国| 亚洲精品日产aⅴ| 操人视频在线观看欧美| 一区二区三区视频免费在线观看| 亚洲人成电影网站色www| 九九久久精品一区| 亚洲最大的成人网| 国产色婷婷国产综合在线理论片a| 免费av一区二区| 精品成人av一区| 欧美精品久久久久久久久| 国产丝袜一区二区| 欧美性猛交xxxx免费看| 久久色免费在线视频| 成人h片在线播放免费网站| 欧美国产高跟鞋裸体秀xxxhd| 亚洲乱亚洲乱妇无码| 欧美国产日韩一区二区三区| 国产精品欧美亚洲777777| 欧洲美女免费图片一区| 亚洲国产精品久久| 中文字幕日韩精品在线观看| 68精品久久久久久欧美| 欧美中文字幕视频| 日韩人体视频一二区| 亚洲人成在线播放| 欧洲永久精品大片ww免费漫画| 97在线视频一区| 欧美成人免费全部观看天天性色| 亚洲乱码国产乱码精品精天堂| 久久91超碰青草是什么| 高清亚洲成在人网站天堂| 亚洲精品视频免费在线观看| 亚洲美女av在线播放| 国产成人精品综合久久久| 国产91免费看片| 国产亚洲日本欧美韩国| 精品福利一区二区| 日韩精品免费在线观看| 亚洲品质视频自拍网| 国产精品偷伦免费视频观看的| 国产亚洲精品美女| 日韩精品福利在线| 中文字幕av日韩| 中文字幕欧美日韩在线| 国产欧美日韩精品在线观看| 亚洲伊人久久综合| 动漫精品一区二区| 欧日韩不卡在线视频| 欧美亚洲免费电影| 欧美日韩成人在线播放| 国产精品免费一区二区三区都可以| 欧美激情中文字幕乱码免费| 久久久久久噜噜噜久久久精品| 黄网动漫久久久| 91精品久久久久久久久不口人| 在线成人中文字幕| 亚洲午夜国产成人av电影男同| 91久久久亚洲精品| 亚洲日本欧美日韩高观看| 欧美一级大片在线免费观看| 性欧美亚洲xxxx乳在线观看| 欧美激情久久久| 欧美国产日韩中文字幕在线| 亚洲四色影视在线观看| 免费91麻豆精品国产自产在线观看| 久久久精品999| 欧美午夜影院在线视频| 国产精品一区二区三|