如何在Golang中调用父方法并将扩展父结构的任何子结构作为参数传递?

huangapple go评论85阅读模式
英文:

How to call parent method and pass any child that extending the parent struct as argument in Golang

问题

我正在学习Golang,我想问一些问题。
是否可以像这样做,并将任何其他扩展Parent结构的子结构传递给PMethod?

type Parent struct{
   PAttribute string
}

func (p *Parent) PMethod(c *Child){
   fmt.Println("this is parent Attribute : " + p.PAttribute)
   fmt.Println("this is child Attribute : " + c.CAttribute)
}

type Child struct{
   Parent
   CAttribute string
}

type Child2 struct{
   Parent
   CAttribute string
}


func main(){
   c := Child{
         Parent{
            "parent"
         },
         "child",
        }
   c.PMethod(&c)

   c2 := Child2{
         Parent{
            "parent"
         },
         "child",
        }
   c2.PMethod(&c2)
}

谢谢

英文:

I'm still learning Golang and I want to ask something.
Is it possible to do something like this and passing any other child to PMethod that extending Parent struct?

type Parent struct{
   PAttribute string
}

func (p *Parent) PMethod(c *Child){
   fmt.Println("this is parent Attribute : " + p.PAttribute)
   fmt.Println("this is child Attribute : " + c.CAttribute)
}

type Child struct{
   Parent
   CAttribute string
}

type Child2 struct{
   Parent
   CAttribute string
}


func main(){
   c := Child{
         Parent{
            "parent"
         },
         "child",
        }
   c.PMethod(&c)

   c2 := Child2{
         Parent{
            "parent"
         },
         "child",
        }
   c2.PMethod(&c2)
}

Thank you

答案1

得分: 5

正如其他人所说,忘掉继承吧,Go语言没有继承,这是有充分理由的。所以不要再用父类和子类的思维方式来思考了。Go语言有组合(你在这里使用了),但它的行为方式不同。你可以在Go语言中使用接口,以便传入Child和Child2,并使接收器对它们的区别不感兴趣(只要它们具有相同的函数)。但是,这可能是一个错误,因为你试图在Go语言中重新创建你熟悉的继承。不要这样做。

如果你的类型之间有关联,你应该从接受类的实例来修改的嵌入类中退一步。嵌入类应该只对自己的字段进行操作,仅此而已——这样可以将关注点分离,并将数据与操作数据的方法放在一起。所以,不要考虑父类和子类,而是考虑一小段你想要共享的代码/数据。

考虑一下经典的继承问题——动物,有猫和狗。使用继承的话,你会有一个Cat类、一个Dog类和一个抽象的基类Animal。Animal可能有你期望的所有方法,然后你在Dogs和Cats上分别写一个Say()方法,Dogs会汪汪叫,Cats会喵喵叫。

在Go语言中,你只需要有Cats和Dogs,并在每个类上有一个不同的Say()方法,它们都符合其他人定义的Speaker()接口。宁愿有一点重复,也不要为了共享一点行为而增加大量的代码和复杂性。

一定要阅读Effective Go,尽量使用现有的工具,而不是重新创建你熟悉的继承等工具。

英文:

As others have said, forget about inheritance, Go doesn't have inheritance for good reasons. So stop thinking in terms of parents and children. Go has composition (which you're using here), but it behaves differently. You could use interfaces in Go in order to pass in Child and Child2 and have the receiver indifferent as to which one it gets (as long as it has the same functions). BUT this is probably a mistake as you're trying to recreate the inheritance you are familiar with in Go. Don't do that.

If your types are related like this, you should probably take a step back from an embedded class accepting instances of a class to modify. The embedded class should act upon its own fields, and that's it - this compartmentalizes concerns and keeps data with the methods that act on it. So instead of thinking about Parents and Children, think about a bit of code/data you want to share.

Consider the classic inheritance problem Animals - with cats and dogs. With inheritance you'd have a Cat and a Dog and an abstract base class Animal. Animal might have all the methods you expect then you write perhaps a Say() method on Animal which says nothing and Say() which woofs and Say() which Meows on Dogs and Cats.

In Go you'd simply have Cats and Dogs and a different Say() method on each which both conform to a Speaker() interface someone else defines. Prefer a bit of duplication to lots of extra code and complexity just to share a little behaviour.

Be sure to read Effective Go and try to use the tools available, rather than recreating tools like inheritance you're familiar with.

huangapple
  • 本文由 发表于 2017年8月31日 14:14:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/45974464.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定