1、結構體方法
go不是純粹的面向物件的,在go里面函式是一等公民,但是go也有結構體實作類似java一樣類的功能來提供抽象,結構體的方法分為值方法和指標方法,前者在方法中做的改變不會改變呼叫的實體物件,后者則會改變,同樣不管是值型別還是指標型別都是可以被呼叫的,因為go結構體底層會自動轉化
比如下面是正常的呼叫:
type Stu struct {
name string
}
func (this Stu) SayName() {
log.Println(this.name)
}
s:=Stu{"Biningo"}
s.SayName()
如果再定義一個方法
func (this *Stu) ChangeName(name string) {
this.name = name
}
因為要改變,所以定義了一個指標型別方法,但是如下呼叫還是可以的
s:=Stu{"Biningo"}
s.ChangeName("xxx") // 會改變
s2:=&Stu{"Biningo"}
s2.ChangeName("xxxx") //會改變
s2.SayName() //會默認轉化 相當于(*s2).SayName() xxxx
注意,go中是不允許方法多載的,同時不管是值型別方法還是指標型別方法名字也不允許一樣
2、匿名屬性和繼承
繼承:
type Camera struct {
name string
}
type Phone struct{}
func (p *Phone) Call() {
fmt.Println("打電話")
}
func (c *Camera) TakePicture() {
fmt.Println("拍照片")
}
type CameraPhone struct {
Camera
Phone
}
繼承只需要結構體內嵌一個要繼承的結構體就可以了,這樣就可以直接使用父類的方法了
phone:=new(CameraPhone)
phone.Call()
phone.TakePicture()
匿名屬性:
type CameraPhone struct {
Camera
Phone
int
}
我們加了一個int型別,這時候相當于加了一個名字為int,型別為int的屬性,名字和型別名一樣
可以如下使用:
phone:=new(CameraPhone)
phone.Call()
phone.TakePicture()
phone.int=1001
但是注意,匿名屬性同型別只允許一個
那么我們允不允許繼承組合一個借口型別呢?那當然也是可以的
下面看一種結構體和介面的組合并且實作多型:
type Clothe interface {
SayColor()
}
type BlueClothe struct {
Color string
}
func (b *BlueClothe) SayColor() {
log.Println("Blue")
}
type RedClothe struct {
Color string
}
func (b *RedClothe) SayColor() {
log.Println("Blue")
}
type Stu struct {
Clothe
Name string
}
func main() {
blue:=&BlueClothe{Color:"Blue"}
var stu Stu
stu.Clothe = blue //匿名型別名字就是型別名
stu.Name="biningo"
stu.SayColor()
}
3、結構體屬性名稱沖突
既然可以隨意繼承組合,并且可以直接由子類呼叫,那如果繼承多個父類有相同的屬性名怎么區分呢?如下:
type A struct {
a,b int
}
type B struct {
a int
}
上面定義了兩個結構體,下面繼承這兩個結構體,注意這里a屬性名字相同
type C struct {A;B}
如下解決沖突
c:=C{A{1,1},B{2}}
fmt.Println(c.A.a,c.B.a) //c.a報錯 需要指明是A還是B的a
還記得匿名欄位吧,這里就相當于點出具體屬性,呼叫具體屬性的屬性
一般匿名欄位的方法是可以直接呼叫的,匿名欄位名呼叫方法的時候是可以忽略欄位名的,相當于是一個縮寫形式
但是如果兩個沖突欄位深度不一樣呢?那就是淺的覆寫深的屬性
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/36317.html
標籤:Go
上一篇:帶你入門etcd
下一篇:Go語言中定時器的使用
