2019独角兽企业重金招聘Python工程师标准>>>
Go语言里面没有面向对象语言里的继承关键字或者语法,所以明面上是没有继承关系的。但是,经过面向对象爱好者的努力,还是在Go语言上实现了模拟继承的功能。下面举个简单例子来说明一下。首先,有一个Dog对象,它实现了Funny接口,从而具备了Funny接口的两种行为:callMyName()和getName()。然后,有一个BDog对象,它没有实现Funny接口,可是它也想具备Funny接口的两种行为:callMyName()和getName(),怎么办呢?在面向对象语言里面,最简单的办法就是BDog继承Dog。这样BDog就自动获得Funny接口的两种能力。 那么,对于Go语言这种没有继承关系的语言该如何处理呢?看看演示代码吧。
package main
import "fmt"
type Dog struct {
name string
}
type BDog struct {
Dog
name string
}
type Funny interface {
callMyName()
getName() string
}
func (this *Dog) callMyName() {
fmt.Printf("my name is %q\n", this.getName())
}
func (this *Dog) getName() string {
return this.name
}
func main() {
b := new(BDog)
b.name = "this is a BDog name"
b.Dog.name = "this is a Dog name"
b.callMyName()
}
代码解读:
首先,程序声明一个Dog结构,并实现 Funny 接口。可以把Dog看做面向对象里的父类。
然后,程序声明一个BDog结构。BDog结构包含一个Dog的成员,而这个Dog成员就是BDog获得Funny 接口能力的关键。
在main方法里面,先new一个BDog对象实例b,然后对BDog对象实例b的成员属性分别赋值,最后,b去调用callMyName()方法。
b为什么能直接调用callMyName()方法呢?因为Go编译器在编译检查过程中,会去遍历结构中的成员,并检查成员中是否有支持
callMyName()的调用。如果只找到一个成员支持这种调用,那么b.callMyName()是合法的。如果是两个或者两个以上的成员都
支持,那么就会报一个调用有歧义的错误。
演示程序运行的结果是:my name is "this is a Dog name" 。 这结果就好像BDog继承了Dog一样,funny。
通过接口和结构的搭配使用,Go语言模拟单继承和多继承是很方便的事情。简单的语言, 强大的表达能力,这就是Go语言。