go結構體繼承組合和匿名字段


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 

還記得匿名字段吧,這里就相當於點出具體屬性,調用具體屬性的屬性

一般匿名字段的方法是可以直接調用的,匿名字段名調用方法的時候是可以忽略字段名的,相當於是一個縮寫形式

但是如果兩個沖突字段深度不一樣呢?那就是淺的覆蓋深的屬性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM