Go面向对象编程实现

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

Go OOP realization

问题

这段代码在Go语言中应该是这样的:

  1. package main
  2. import "fmt"
  3. type MyParent interface {
  4. doSomething()
  5. internal() string
  6. }
  7. type Parent struct{}
  8. func (p Parent) internal() string {
  9. return p.doSomething()
  10. }
  11. type MyChild struct {
  12. Parent
  13. }
  14. func (c MyChild) doSomething() {
  15. fmt.Println("Test")
  16. }
  17. func main() {
  18. child := MyChild{}
  19. child.doSomething()
  20. }

在父类中如何访问子类的方法,即使子类还未定义呢?在Go语言中,我们可以使用接口来实现这个功能。在上面的代码中,我们定义了一个MyParent接口,其中包含了doSomething()internal()方法。然后,我们定义了一个Parent结构体,并实现了internal()方法。接着,我们定义了MyChild结构体,并嵌入了Parent结构体。最后,在MyChild结构体中实现了doSomething()方法。通过这样的设计,我们可以在父类中调用子类的方法。在main()函数中,我们创建了一个MyChild对象,并调用了doSomething()方法。

英文:

How should this code snippet look like in Go? How can I access to method of child class from parent class when child class is not defined yet?

  1. class Parent {
  2. abstract class MyParent {
  3. abstract function doSomething();
  4. function internal() {
  5. return static::doSomething();
  6. }
  7. }
  8. class MyChild extends MyParent {
  9. function doSomething() {
  10. return 'Test';
  11. }
  12. }

答案1

得分: 2

如@icza所说,Go语言中没有继承(这是一个优点)。最接近的方法是嵌入父类型。

  1. type Parent struct {}
  2. func (p *Parent) doSomething() {
  3. fmt.Println("Test")
  4. }
  5. type MyChild struct {
  6. Parent
  7. }
  8. func main() {
  9. child := &MyChild{}
  10. child.doSomething() // 输出 "Test"
  11. }

请参考https://golang.org/doc/effective_go.html#embedding

英文:

As @icza said, there's no inheritance in Go (which is a sweet spot). The closest would be embedding a Parent's type.

  1. type Parent struct {}
  2. func (p *Parent) doSomething() {
  3. fmt.Println("Test")
  4. }
  5. type MyChild struct {
  6. Parent
  7. }
  8. func main() {
  9. child := &MyChild{}
  10. child.doSomething() // print "Test"
  11. }

Check out https://golang.org/doc/effective_go.html#embedding

答案2

得分: 0

//这被称为接口
type Parent interface{
doSomething() string
}
//在定义实现之前使用接口
func JustPrint(p Parent){
fmt.Println(p.doSomething())
}
//定义MyChild
type MyChild SomeType
//您不必显式实现接口
//只需定义所需的方法即可
func (mc MyChild) doSomething() string{
return "测试"
}

英文:
  1. //It's called interface
  2. type Parent interface{
  3. doSomething() string
  4. }
  5. //Use interface before defining implementation
  6. func JustPrint(p Parent){
  7. fmt.Println(p.doSomething())
  8. }
  9. //Define MyChild
  10. type MyChild SomeType
  11. //You do not have to implement interface explicitly
  12. //Just to define method needed would be enough
  13. func (mc MyChild) doSomething() string{
  14. return "Test"
  15. }

答案3

得分: 0

我相信你最终想要实现的是类似于“模板方法”设计模式的东西。

在软件工程中,模板方法模式是一种行为设计模式,它在一个称为模板方法的方法中定义了算法的程序骨架,并将一些步骤推迟到子类中。

AFAIK,在Go语言中实现类似的功能的唯一正确方法是使用接口,就像@pie-o-pah和@icza所说的那样。我说“类似于”,是因为你不能使用接口作为方法的接收者(也就是说,在Go语言中没有部分抽象类型的概念)。

一个正确的实现应该是这样的:

  1. package main
  2. import "fmt"
  3. // --------------------------
  4. // 将纯抽象类型定义为接口
  5. type MyParent interface {
  6. doSomething() string
  7. }
  8. // 定义一个函数(你的模板方法),它操作该接口;
  9. // 接口不能作为函数的接收者,但它总是可以作为参数
  10. func internal(m MyParent) string {
  11. return m.doSomething()
  12. }
  13. // 定义实现
  14. type MyChild struct{}
  15. // 实现接口的方法
  16. func (m *MyChild) doSomething() string {
  17. return "Test"
  18. }
  19. // 在Go语言中,任何实现了给定接口的所有方法的类型都会隐式地实现该接口,
  20. // 但你可以使用以下技巧“强制”编译器为你检查(基本上是尝试将接口的实例分配给变量,然后将其丢弃)
  21. var _ MyParent = (*MyChild)(nil)
  22. // -------------------------------
  23. // 测试代码
  24. func main() {
  25. m := &MyChild{}
  26. fmt.Println(m.doSomething())
  27. fmt.Println(internal(m))
  28. }

希望对你有所帮助!

英文:

I believe what you are trying to accomplish, in the end, is something akin to the "Template method" design pattern:

> In software engineering, the template method pattern is a behavioral
> design pattern that defines the program skeleton of an algorithm in a
> method, called template method, which defers some steps to subclasses.

https://en.wikipedia.org/wiki/Template_method_pattern

AFAIK, the only correct way to achieve something like this in Go is to use interfaces as @pie-o-pah and @icza have said. I say "something like", because you cannot define methods with interfaces as receivers (i.e. there is no such thing as partially abstract type in Go).

A correct implementation would look like this:

  1. package main
  2. import "fmt"
  3. // --------------------------
  4. // define your purely abstract type as an interface
  5. type MyParent interface {
  6. doSomething() string
  7. }
  8. // define a function (your template method) which operates
  9. // on that interface; an interface cannot be a function receiver,
  10. // but it can always be a parameter
  11. func internal(m MyParent) string {
  12. return m.doSomething()
  13. }
  14. // define the implementation
  15. type MyChild struct {}
  16. // implement the methods for the interface
  17. func (m *MyChild) doSomething() string {
  18. return "Test"
  19. }
  20. // in Go any type which implements all methods in a given interface
  21. // implements that interface implicitly, but you can "force" the
  22. // compiler to check that for you using the following trick
  23. // (basically try to assign a an instance of the interface to a variable,
  24. // then discard it)
  25. var _ MyParent = (*MyChild)(nil)
  26. // -------------------------------
  27. // test code
  28. func main() {
  29. m := &MyChild{}
  30. fmt.Println(m.doSomething())
  31. fmt.Println(internal(m))
  32. }

huangapple
  • 本文由 发表于 2016年3月30日 21:10:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/36309866.html
匿名

发表评论

匿名网友

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

确定