在其他父方法中使用重写的父方法

时间:2016-09-03 21:19:22

标签: go

我有两种类型,B和C,它们共享所有方法,但以不同方式实现其中一种。我想通过使用父类型A来表达这一点,包含共享方法的实现,并在A和B中嵌入A.(不要重复自己!)障碍是B和B之间的方法不同在许多共享方法中调用C.构建此类代码的惯用方法是什么?

我当前的实现看起来基本上是这样的(https://play.golang.org/p/RAvH_hBFDN;基于Dave Cheney的示例):

package main

import (
    "fmt"
)

type Legger interface {
    Legs() int
}

type Cat struct {
    Name string
    L    Legger
}

// Cat has many methods like this, involving calling c.L.Legs()
func (c Cat) PrintLegs() {
    fmt.Printf("I have %d legs.\n", c.L.Legs())
}

// OctoCat is a Cat with a particular implementation of Legs
type OctoCat struct {
    Cat
}

func (c OctoCat) Legs() int {
    return 8
}

// TetraCat has a different implementation of Legs
type TetraCat struct {
    Cat
}

func (c TetraCat) Legs() int {
    return 4
}

func main() {
    c := TetraCat{Cat{"Steve",nil}}
    c.L = &c
    c.PrintLegs() // want 4
    o := OctoCat{Cat{"Bob",nil}}
    o.L = &o
    o.PrintLegs() // want 8
}

类型定义本身看起来很干净,但是main中的初始化代码很古怪(首先是struct literal中的nil,然后是c.L = &c,是什么?)。有更好的解决方案吗?

is it possible to call overridden method from parent struct in golang?中提出了类似的模式,但是这是否是惯用的方法尚未得到解答。

1 个答案:

答案 0 :(得分:1)

我会考虑解决这个问题的两种方法:

1。将您的代码重构为包含字段CatName string的单个Legs int类型:

package main

import (
    "fmt"
)

type Cat struct {
    Name string
    Legs int
}

func (c *Cat) PrintLegs() {
    fmt.Printf("I have %d legs.\n", c.Legs)
}

func main() {
    c := &Cat{"Steve", 4}
    c.PrintLegs() // want 4
    o := &Cat{"Bob", 8}
    o.PrintLegs() // want 8
}

https://play.golang.org/p/_PNAu3sgG8

2。取消Cat类型,只需TetraCatOctoCat实现Legger界面:

package main

import (
    "fmt"
)

type Legger interface {
    Legs() int
}

func PrintLegs(l Legger) {
    fmt.Printf("I have %d legs.\n", l.Legs())
}

// OctoCat is a Cat with a particular implementation of Legs
type OctoCat struct {
    Name string
}

func (c *OctoCat) Legs() int {
    return 8
}

// TetraCat has a different implementation of Legs
type TetraCat struct {
    Name string
}

func (c *TetraCat) Legs() int {
    return 4
}

func main() {
    c := &TetraCat{"Steve"}
    PrintLegs(c) // want 4
    o := &OctoCat{"Bob"}
    PrintLegs(o) // want 8
}

https://play.golang.org/p/m4QvKhSj0w