内嵌的结构体如何调用其外部结构体的方法?

flyinmysky · 2018-01-29 14:08:07 · 1746 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-01-29 14:08:07 的主题,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
)

type Animal struct{}

func (a *Animal) Escape() {
    a.Run()
}

func (a *Animal) Run() {
    fmt.Printf("Animal Run.\n")
}

type Dog struct {
    Animal
}

func (d *Dog) Run() {
    fmt.Printf("Dog Run.\n")
}

func main() {
    dog := Dog{}
    dog.Escape()
}

运行结果为:Animal Run. 但我想要的结果应该是:Dog Run.

这个要怎么实现?

我可能还是用的类的方式思考的,子类Dog继承了基类Animal ,并重写了Run方法。在子类中调用Escape时,Escape再调用Run时,应该也是调用的子类的Run。但是由于在Go语言中,在Dog调用Escape时,由于Dog并没有自己实现Escape而是继承的Animal 的方法,所以接收者是Animal ,再调用Run就是调用的Animal 的Run。

我要怎么才能在这种情况下调用到我重写后的Run呢?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1746 次点击  
加入收藏 微博
11 回复  |  直到 2018-02-12 10:03:34
304158
304158 · #1 · 7年之前

我记得反射的情况下,如果是一个结构实现了一个接口,可以用强制转换成接口在调用接口方法

304158
304158 · #2 · 7年之前
304158304158 #1 回复

我记得反射的情况下,如果是一个结构实现了一个接口,可以用强制转换成接口在调用接口方法

这样的想法下,你的Dog也要实现一个Escape才可能实现吧。。。

mojiajuzi
mojiajuzi · #3 · 7年之前

结构体的内嵌规则问题,因为Dog结构体,没有对应的Escape方法,所以这里的dog.Escape等效于dog.Animal.Excape方法

mojiajuzi
mojiajuzi · #4 · 7年之前
mojiajuzimojiajuzi #3 回复

结构体的内嵌规则问题,因为Dog结构体,没有对应的Escape方法,所以这里的`dog.Escape`等效于`dog.Animal.Excape`方法

抱歉题主,请忽略这一条

flyinmysky
flyinmysky · #5 · 7年之前

编程中难免遇到这种情况,就是有些方法可以继承父类的,有些又需要重写。但是继承自父类的方法就不能调用重写之后的方法,不知道有没有什么好的解决方法。

304158
304158 · #6 · 7年之前
package main

import (
    "fmt"
    "reflect"
)
type IAnimal interface {
    Run()
}
type Animal struct{}

func (a *Animal) Escape(ianimal IAnimal) {
    ianimal.Run()
}

func (a *Animal) Run() {
    fmt.Printf("Animal Run.\n")
}

type Dog struct {
    Animal
}

func (d *Dog) Run() {
    fmt.Printf("Dog Run.\n")
}

func main() {
    dog := &Dog{}
    dogv:=reflect.ValueOf(dog)
    dogt:=reflect.Indirect(dogv).Type()
    dognew:=reflect.New(dogt)
    dogi:=dognew.Interface().(IAnimal)
    dog.Escape(dogi)
}
304158
304158 · #7 · 7年之前
304158304158 #6 回复

```go package main import ( "fmt" "reflect" ) type IAnimal interface { Run() } type Animal struct{} func (a *Animal) Escape(ianimal IAnimal) { ianimal.Run() } func (a *Animal) Run() { fmt.Printf("Animal Run.\n") } type Dog struct { Animal } func (d *Dog) Run() { fmt.Printf("Dog Run.\n") } func main() { dog := &Dog{} dogv:=reflect.ValueOf(dog) dogt:=reflect.Indirect(dogv).Type() dognew:=reflect.New(dogt) dogi:=dognew.Interface().(IAnimal) dog.Escape(dogi) } ```

package main

import (

    "fmt"
    "reflect"

)

type IAnimal interface {

    Run()

}

type Animal struct{}


func (a *Animal) Escape(ianimal IAnimal) {

    ianimal.Run()
}


func (a *Animal) Run() {

    fmt.Printf("Animal Run.\n")

}


type Dog struct {

    Animal
}


func (d *Dog) Run() {

    fmt.Printf("Dog Run.\n")
}

func main() {

dog := &Dog{}
dogv:=reflect.ValueOf(dog)
dogt:=reflect.Indirect(dogv).Type()
dognew:=reflect.New(dogt)
dogi:=dognew.Interface().(IAnimal)
dog.Escape(dogi)

}

304158
304158 · #8 · 7年之前
package main

import  "fmt"

type IAnimal interface {

    Run()

}
type Animal struct{}

func (a *Animal) Escape(ianimal IAnimal) {

    ianimal.Run()

}

func (a *Animal) Run() {

    fmt.Printf("Animal Run.\n")
}

type Dog struct {

    s Animal
}

func (d *Dog) Run() {

    fmt.Printf("Dog Run.\n")
}

func main() {

    dog := &Dog{}
    dog.s.Escape(dog)
    ad:=&Animal{}
    ad.Escape(ad)

}

//输出
//Dog Run.
//Animal Run.

flyinmysky
flyinmysky · #9 · 7年之前

ad.Escape(ad),调用自己的方法的时候,还要传入自己,感觉怪怪的。

guanchaoguo
guanchaoguo · #10 · 7年之前
package main

import  "fmt"

type IAnimal interface {

    Run()

}
type Animal struct{}

func (a *Animal) Escape() {

    a.Run()

}

func (a *Animal) Run() {

    fmt.Printf("Animal Run.\n")
}

type Dog struct {

     Animal
}

func (d *Dog) Run() {

    fmt.Printf("Dog Run.\n")
}

func main() {

    dog := &Dog{}
    dog.Run()
    dog.Animal.Escape()

}
GreatBedAwake
GreatBedAwake · #11 · 7年之前

go的采用组合的方式来实现继承。

package main

import (
    "fmt"
)

type IAnimal interface {
    Run()
    Escape()
}
type Animal struct{
    Name string
}

func NewAnimal() IAnimal{
    return &Animal{"Animal"}
}

func (a *Animal) Escape() {
    a.Run()
}

func (a *Animal) Run() {

    fmt.Printf("%s Run.\n", a.Name)
}

type Dog struct {
    Animal
}

func NewDog() IAnimal{
    d := &Dog{}
    d.Name = "Dog"
    return d
}


func main() {
    dog := NewDog()
    dog.Run()
    dog.Escape()

}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传