golang 父类调用子类方法、继承多态的实现方式

tmj 2019-06-29

实现思路

go 语言中,当子类调用父类方法时,“作用域”将进入父类的作用域,看不见子类的方法存在(个人想象的)

我们可以通过参数将子类传递给父类,实现在父类中调用子类方法。

实现方式有两种:

一、 基于接口

定义接口,父子类都实现接口,父类方法接收接口类型参数

特点:

  • 结构简单,思路清晰。
  • 基于接口,轻松应对多级继承的情况。
推荐使用这种方式

直接上代码:

package main

import (
    "fmt"
)

type Name interface {
    Name() string
}

type A struct {
}

func (self A) say() {
    println(self.Name())
}

func (self A) sayReal(child Name) {
    fmt.Println(child.Name())
}

func (self A) Name() string {
    return "I'm A"
}

type B struct {
    A
}

func (self B) Name() string {
    return "I'm B"
}


type C struct {
    A
}

func main() {
    b := B{}
    b.say()         //I'm A
    b.sayReal(b)    //I'm B

    c := C{}
    c.say()         //I'm A
    c.sayReal(c)    //I'm A
}

二、 基于反射

父类方法接收子类对象,通过反射调用子类方法

直接上代码:

package main

import (
    "fmt"
    "reflect"
)

type A struct {
}

func (self A) say() {
    println(self.Name())
}

func (self A) sayReal(child interface{}) {
    ref := reflect.ValueOf(child)
    method := ref.MethodByName("Name")
    if (method.IsValid()) {
        r := method.Call(make([]reflect.Value, 0))
        fmt.Println(r[0].String())
    } else {
        // 错误处理
    }
}

func (self A) Name() string {
    return "I'm A"
}

type B struct {
    A
}

func (self B) Name() string {
    return "I'm B"
}


type C struct {
    A
}

func main() {
    b := B{}
    b.say()         //I'm A
    b.sayReal(b)    //I'm B

    c := C{}
    c.say()         //I'm A
    c.sayReal(c)    //I'm A
}

相关推荐