总结两点:
在Go中,定义一个interface类型,该类型说明了它有哪些方法。使用时,在函数中,将该interface类型作为函数的形参,任意一个实现了interface类型的实参都能作为该interface的实例对象。Go中没有implements关键字,与Java的实现多态相比,Go的组合更加灵活。
Go语言中没有继承,只有组合,可通过组合达到“继承”方法的目的。
先看一个例子:
/** * Animal 三个接口:fly(), swim() 和 run(),如果实现Animal,需要同时实现三个接口。 */ public interface Animal { public void fly(); public void swim(); public void run(); } class Dog implements Animal { @Override public void fly() { System.out.println("Dog can not fly"); } @Override public void swim() { System.out.println("Dog can not swim"); } @Override public void run() { System.out.println("Dog can run"); } } class Fish implements Animal { @Override public void fly() { System.out.println("Fish can not fly"); } @Override public void swim() { System.out.println("Fish can swim"); } @Override public void run() { System.out.println("Fish can not run"); } }
再来看Go的实现:
type Animal1 interface { fly() swim() run() } type Dog1 struct { } func (d Dog1) run() { fmt.Println("dog can run") } type Fish struct { } func (f Fish) swim() { fmt.Println("fish can swim") }
可以看到,Go中实现需要的功能更灵活。这是多个实现类之间的比较,实现更加灵活。再看类似于“父子”之间的继承。
import ( "fmt" "reflect" ) type Base struct { // nothing } func (b *Base) ShowA() { fmt.Println(reflect.TypeOf(b)) fmt.Println("showA") b.ShowB() } func (b *Base) ShowB() { fmt.Println(reflect.TypeOf(b)) fmt.Println("showB") } func (b *Base) ShowC() { fmt.Println(reflect.TypeOf(b)) fmt.Println("showC") } //Derived 通过组合Base结构体,实现了伪继承,即拥有了ShowA和ShowB方法 type Derived struct { Base } //Derived 自己实现了ShowB方法,但不会自动做类型转换 func (d *Derived) ShowB() { fmt.Println(reflect.TypeOf(d)) fmt.Println("Derived showB") } type NewBase Base func main2() { d := Derived{Base{}} d.ShowA() //Derived通过组合,有了ShowA()方法 /** *main.Base showA *main.Base showB 上述代码执行结果不会输出“Derived showB”,因为Go中没有继承的概念,只有组合. 上面的Derived包含了Base,自动的含有了Base的方法,因为其不是继承,所以不会根据具体传入的对象而执行对应的方法。 */ d.ShowB() /** *main.Derived Derived showB */ d.Base.ShowB() /** *main.Base showB d 通过组合获取了Base的方法 ShowB. 但如果d要调取Base的ShowB()方法(与d的ShowB()方法重复),需要显示调用Base. */ d.ShowC() /** *main.Base showC d 通过组合获取了Base的方法 ShowC. */ b := Base{} b.ShowC() //b1 := NewBase{} //b1.ShowC() //没有ShowC()方法 /** 上面的代码中b1不能执行ShowC()函数,因为Golang不支持隐式类型转换. 虽然newBase就是Base,但语法上它们是两种类型,因此newBase不能执行ShowC()方法。 */ }
发表评论 取消回复