Go语言使用接口(interface)和结构(struct)来模拟对象继承

Go语言里面没有面向对象语言里的继承关键字或者语法,因此明面上是没有继承关系的。可是,通过面向对象爱好者的努力,仍是在Go语言上实现了模拟继承的功能。下面举个简单例子来讲明一下。首先,有一个Dog对象,它实现了Funny接口,从而具有了Funny接口的两种行为:callMyName()和getName()。而后,有一个BDog对象,它没有实现Funny接口,但是它也想具有Funny接口的两种行为:callMyName()和getName(),怎么办呢?在面向对象语言里面,最简单的办法就是BDog继承Dog。这样BDog就自动得到Funny接口的两种能力。 那么,对于Go语言这种没有继承关系的语言该如何处理呢?看看演示代码吧。
this

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()
}

代码解读:spa

首先,程序声明一个Dog结构,并实现 Funny 接口。能够把Dog看作面向对象里的父类。code

而后,程序声明一个BDog结构。BDog结构包含一个Dog的成员,而这个Dog成员就是BDog得到Funny 接口能力的关键。对象

在main方法里面,先new一个BDog对象实例b,而后对BDog对象实例b的成员属性分别赋值,最后,b去调用callMyName()方法。继承

b为何能直接调用callMyName()方法呢?由于Go编译器在编译检查过程当中,会去遍历结构中的成员,并检查成员中是否有支持 接口

callMyName()的调用。若是只找到一个成员支持这种调用,那么b.callMyName()是合法的。若是是两个或者两个以上的成员都get

支持,那么就会报一个调用有歧义的错误。编译器

演示程序运行的结果是:my name is "this is a Dog name" 。 这结果就好像BDog继承了Dog同样,funny。string

经过接口和结构的搭配使用,Go语言模拟单继承和多继承是很方便的事情。简单的语言, 强大的表达能力,这就是Go语言。编译

相关文章
相关标签/搜索