一、型別方法的實體成員復制與型別方法的實體成員參考
??在Go中可以類似Java等面向物件語言一定為某個物件定義方法,但是Go中并沒有類的存在,可以不嚴格的將Go中的struct型別理解為面向物件中的類;
type demoObject struct {
id int
}
??類的概念有了,那怎么為這個類(struct結構)定義方法呢;Go語言中有兩種方式:
1、在型別指標上定義方法;
func (o *demoObject) one() {
fmt.Printf("one方法欄位的記憶體地址:%x\n",
unsafe.Pointer(&o.id))
}
2、在型別上定義方法;
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值不會變化
二、介面與實作
??在Go中實作某介面不需要顯式的依賴該介面,只需要在某型別或型別指標上定義與該介面的方法簽名完全一致的介面即可;
type inter interface {
hello()
}
func (o *demoObject) hello() {
}
var i inter = new(demoObject)
i.hello()
??如上代碼所示,即可說型別demoObject實作了inter介面,Go的介面具有非入侵性,由于該特性因此Go語言也具有了dock typing ,也就是鴨子型別;
三、內嵌型別(類似繼承并非等同于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的方法,兩者并非繼承與被繼承的關系;
四、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類類似但又不一樣;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/53029.html
標籤:Go
上一篇:[系列] Go 使用 defer 函式 要注意的幾個點
下一篇:slice 實作原理
