1、類型方法的實例成員複製與類型方法的實例成員引用
在Go中能夠相似Java等面嚮對象語言必定爲某個對象定義方法,可是Go中並無類的存在,能夠不嚴格的將Go中的struct類型理解爲面向對象中的類;函數
type demoObject struct { id int }
類的概念有了,那怎麼爲這個類(struct結構)定義方法呢;Go語言中有兩種方式:
一、在類型指針上定義方法;指針
func (o *demoObject) one() { fmt.Printf("one方法字段的內存地址:%x\n", unsafe.Pointer(&o.id)) }
二、在類型上定義方法;code
func (o demoObject) two() { fmt.Printf("one方法字段的內存地址:%x\n", unsafe.Pointer(&o.id)) }
這兩種方式其實定義方式都差很少,區別只是在於方法時定義在類型上仍是定義在類型指針上面,就是由於這點區別致使了方法中類型實例有了本質的區別;
在類型上定義方法其類型實例的成員值會進行復制,也就是說每一個該類型實例的方法中類型的成員地址也都不同;
而在類型指針上定義方法其類型實例的成員只是指針複製,全部類型指針上方法的類型成員地址徹底同樣;對象
var obj = new(demoObject) fmt.Printf("main函數obj對象字段的內存地址:%x\n", unsafe.Pointer(&obj.id)) obj.one() obj.two()
one方法:o實例的成員id內存地址與obj實例的成員id地址同樣
two方法:o實例的成員id內存地址與obj實例的成員id地址不同
總結來講:
one方法中修改demoObject類型的成員id的值obj實例成員id值也會變化
two方法中修改demoObject類型的成員id的值obj實例成員id值不會變化繼承
2、接口與實現
在Go中實現某接口不須要顯式的依賴該接口,只須要在某類型或類型指針上定義與該接口的方法簽名徹底一致的接口便可;接口
type inter interface { hello() } func (o *demoObject) hello() { } var i inter = new(demoObject) i.hello()
如上代碼所示,便可說類型demoObject實現了inter接口,Go的接口具備非入侵性,因爲該特性所以Go語言也具備了dock typing ,也就是鴨子類型;內存
3、內嵌類型(相似繼承並不是等同於Java中的繼承)
Go中存在這一種匿名內嵌類型,經過匿名內嵌類型能夠獲得相似與繼承的結果;引用
type base struct { Id int } type level struct { *base } var l=new(level) fmt.Println(l.Id)
如上代碼所示,經過在類型level中引入匿名內嵌類型base,可使用level類型的實例l調用獲得類型base中的成員Id,若是base類型有綁定方法level類型實例同樣能夠調用該方法。
請注意上面說的是經過內嵌類型能夠獲得的是相似繼承,並不是等同於繼承,level實例雖然能夠訪問獲得base類型實例,但並不能在level中重寫base的方法。二者並不是繼承與被繼承的關係;方法
4、Go中的多態
Go有接口的存在,是否也存在多態的概念呢。 答案是存在的以下代碼所示,與Java中的多態並無很大區別;總結
type one struct{} type two struct{} type inter interface { hello() } func (o *one) hello() { fmt.Println("one hello") } func (t *two) hello() { fmt.Println("two hello") } func say(i inter) { i.hello() } var o = new(one) var t = new(two) say(o) say(t)
Golang中存在面向對象的某些特徵,但又與傳統的面嚮對象語言有着不小區別;如Go中只有相似繼承功能,又不等同於其餘語言的繼承,沒法重寫方法,也不存在子類於父類的概念;Go中存在接口但空接口表明着是任意類型於Java中的Object類相似但又不同;