這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
interface是golang的抽象設計的根基,是方法集合的介面,是一個非常強大的並且規範的指標,可以引用任意實現了該介面的方法集合的struct,不能定義屬性,意味著在抽象設計裡是不允許有資料的,使語言的編譯運行管理更純粹方便。
一切屬性都是setter/getter
1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
package maintype Surface struct{ skin string}func (s *Surface) Skin() string{ return "My skin is " + s.skin}type Men interface { GetSurface() Surface}type European struct { surface Surface}func (p *European) GetSurface() Surface{ return p.surface}type African struct { surface Surface}func (p *African) GetSurface() Surface{ return p.surface}func Introduce(men Men){ s := men.GetSurface() println(s.Skin())}func main() { var s Surface s = Surface{"white"} e := European{s} Introduce(&e) s = Surface{"black"} a := African{s} Introduce(&a)} |
上例中的多態,通過setter/getter變相完成了property在interface定義,用方法多態來實現屬性多態。
父類方法A調用子類方法B
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
package maintype Men interface { Age() int}type Parent struct { Men //隱式 m Men //顯式}func (p *Parent) Age() int{ return 80}func (p *Parent) Display1() { println(p.Men.Age())}func (p *Parent) Display2() { println(p.m.Age())}type Child struct { Parent}func (c *Child) Age() int{ return 40}func main() { var child *Child var parent *Parent parent = &Parent{parent, nil} child = &Child{Parent: *parent} println("====parent") child.Display1() parent = &Parent{child, nil} child = &Child{Parent: *parent} println("====child") child.Display1() child.m = parent println("====parent") child.Display2() child.m = child println("====child") child.Display2()} |
上例中的實現了在父類的A方法中調用父類或者子類的B方法,類似於抽象方法。因為go是靜態語言,沒有動態語言強大的尋找機制,也沒有虛函數(virtural method)和抽象方法(abstract method)之類的輔助進階別的多態。
幸好,golang有指標,即interface,又名介面,通過在父類定義介面類型的屬性,並在執行個體化的時候動態綁定該屬性的真正類型,來完成父類方法中一些多態方法的靈活調用,增加了公用部分的複用性。