golang 父類調用子類方法、繼承多態的實現方式

實現思路

go 語言中,當子類調用父類方法時,「做用域」將進入父類的做用域,看不見子類的方法存在(我的想象的)code

咱們能夠經過參數將子類傳遞給父類,實如今父類中調用子類方法。對象

實現方式有兩種:

1、 基於接口

定義接口,父子類都實現接口,父類方法接收接口類型參數繼承

特色:接口

  • 結構簡單,思路清晰。
  • 基於接口,輕鬆應對多級繼承的狀況。
推薦使用這種方式

直接上代碼:作用域

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
}

2、 基於反射

父類方法接收子類對象,經過反射調用子類方法string

直接上代碼:class

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
}
相關文章
相關標籤/搜索