Go lang的多态性

are*_*ler 13 oop polymorphism go

我正在学习go lang,我想知道是否有办法做这样的事情:

type Foo struct {
   ...
}

type Bar struct {
   Foo
   ...
}

func getFoo() Foo {
   return Bar{...}
}
Run Code Online (Sandbox Code Playgroud)

在面向对象的语言中,这样的代码应该没有问题,但是在它中它会抛出一个错误,说getFoo()必须返回类Foo的实例.

有没有办法做多边形,类似于我在Go中所描述的?

小智 13

Go不是典型的OO语言.每种语言都有自己的做事方式.您可以使用界面和组合来实现您的期望,如下所示:

package main

import "fmt"

type Foo interface {
   printFoo()
}

type FooImpl struct {

}

type Bar struct {
   FooImpl
}

type Bar2 struct {
   FooImpl
}

func (f FooImpl)printFoo(){
    fmt.Println("Print Foo Impl")
}

func getFoo() Foo {
   return Bar{}
}

func main() {
    fmt.Println("Hello, playground")
    b := getFoo()
    b.printFoo()
}
Run Code Online (Sandbox Code Playgroud)

http://play.golang.org/p/iR8QkD3DnP

  • 我认为你将"interface"与"interface {}"混淆了.. Go仍然会在编译时键入check interfaces,它只会检查变量是否是该接口的一个实例."interface {}"的问题在于,由于需要为接口匹配的函数是空集,所以一切都匹配它,并且您将失去编译时类型检查. (4认同)

Pie*_*Pah 5

在Go中,通过实现接口来实现多态。

type Being interface {
        somemethod()
}

type Foo struct {}

type Bar struct {
        Foo
}

type Baz struct {
        Foo
}

// `Bar` and `Baz` implement `Being`
func (b *Bar) somemethod() {}
func (b *Baz) somemethod() {}

func getAnyFoo(b *Being) Foo {
   return b.Foo
}
Run Code Online (Sandbox Code Playgroud)

因此,任何东西都会实现一个空接口。

type Foo struct {}

type Bar struct {
        Foo
}

// Get anything and extract its `Foo` if anything is a Bar
func getAnyFoo(i interface{}) Foo {
        // Normally this would need a type switch to check the type
        mybar := i.(Bar)
        return mybar.Foo
}
Run Code Online (Sandbox Code Playgroud)