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 Surfaces = 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 *Childvar parent *Parentparent = &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 = parentprintln("====parent")child.Display2()child.m = childprintln("====child")child.Display2()}
上例中的实现了在父类的A方法中调用父类或者子类的B方法,类似于抽象方法。因为go是静态语言,没有动态语言强大的查找机制,也没有虚函数(virtural method)和抽象方法(abstract method)之类的辅助高级别的多态。
幸好,golang有指针,即interface,又名接口,通过在父类定义接口类型的属性,并在实例化的时候动态绑定该属性的真正类型,来完成父类方法中一些多态方法的灵活调用,增加了公共部分的复用性。