Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call child method in parent method? [duplicate]

Tags:

go

package main

import "fmt"

type Super struct{}

func (super *Super) name() string {
    return "Super"
}

func (super *Super) WhoAmI() {
    fmt.Printf("I'm %s.\n", super.name())
}

type Sub struct {
    Super
}

func (sub *Sub) name() string {
    return "Sub"
}

func main() {
    sub := &Sub{Super{}}
    sub.WhoAmI()
}

I want to get "I'm Sub", but I get "I'm Super" instead.

I already know sub.WhoAmI will call sub.Super.WhoAmI, but I still want to know if there is a way to get "I'm Sub". In Python when I write following code:

class Super(object):

    def name(self):
        return "Super"

    def WhoAmI(self):
        print("I'm {name}".format(name=self.name()))

class Sub(Super):

    def name(self):
        return "Sub"


if __name__ == "__main__":
    sub  = Sub()
    sub.WhoAmI()

I can get "I'm Sub".

like image 464
QthCN Avatar asked Nov 18 '15 15:11

QthCN


People also ask

How do you call parent method from child method?

Call Parent Component method from Child Component For Calling Parent Component method from Child Component, I had created a method getParentMethod and in this method, I had set input property in HTML file of parent component. Then shown as below code inside the child component I am able to access parent method.


2 Answers

Embedding is not subclassing. There are no superclasses or subclasses in Go. Sub here is not a "child" of Super. It contains a Super. You can't do you're trying to do. You need to organize your code in a different way so that it's not needed.

For example, here (playground) is a more natural way to do this in Go:

package main

import "fmt"

type Namer interface {
    Name() string
}

type Super struct{}

func (sub *Super) Name() string {
    return "Super"
}

type Sub struct{}

func (sub *Sub) Name() string {
    return "Sub"
}

func WhoAmI(namer Namer) {
    fmt.Printf("I'm %s.\n", namer.Name())
}

func main() {
    sub := &Sub{}
    WhoAmI(sub)
}

Rather than focus on classes (which Go doesn't have), this focuses on interfaces. It's not a question of what things are, it's a question of what they can do. This is a very powerful approach to programming, and in practice is often much more flexible and less error-prone than inheritance abstractions.

like image 71
Rob Napier Avatar answered Sep 20 '22 15:09

Rob Napier


Think of functions in Go as if they all belong to a single namespace. Go really doesn’t have classes, methods, or inheritance, so what you’re attempting will never work the way you intend.

To put it another way, when you define a function like this:

func (f *Foo) DoStuff()

You can imagine it really being defined as:

func DoStuff(f *Foo)

So you might notice why Go chose to call the name function on your Super struct—it was the only function signature that matched. (Note that in your WhoAmI function super is defined as super *Super so Go matches it up with the corresponding function of the same type.)

As for how you might do this the Go way, try using interfaces:

http://play.golang.org/p/8ELw-9e7Re

package main

import "fmt"

type Indentifier interface {
    WhoAmI() string
}

type A struct{}

func (a *A) WhoAmI() string {
    return "A"
}

type B struct{}

func (b *B) WhoAmI() string {
    return "B"
}

func doSomething(x Indentifier) {
    fmt.Println("x is a", x.WhoAmI())
}

func main() {
    doSomething(&A{})
    doSomething(&B{})
}
like image 41
Todd Yandell Avatar answered Sep 21 '22 15:09

Todd Yandell