go構造体継承組合せと匿名フィールド

2668 ワード

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

ただし、匿名属性は同じタイプで1つしか許可されていません.
では、私たちは言い訳のタイプを継承することを許可しますか?それはもちろんいいです.
次に、構造体とインタフェースの組み合わせを見て、マルチステートを実現します.
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
}

上に2つの構造体が定義され、下にこの2つの構造体が継承され、ここで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 

匿名のフィールドを覚えていますね.ここでは、特定の属性を呼び出し、特定の属性を呼び出すことに相当します.
一般的な匿名フィールドのメソッドは直接呼び出すことができ、匿名フィールド名呼び出しメソッドはフィールド名を無視することができ、略語形式に相当する.
しかし、2つの競合フィールドの深さが異なる場合は?それは浅い覆い深さの属性です