golang:关于接口实现继承的问题

时间:2019-08-27 15:28:37

标签: go

这个问题是关于在golang中“继承”接口实现的最干净方法。我了解Go没有继承权;这个问题是关于人们如何以其他方式实现的,因此是关于继承的引号。

假设有一个定义的标准库接口,例如container/heaphttps://golang.org/pkg/container/heap/#Interface

可以说有一个名为.go的{​​{1}}文件可以实现该接口:

pq.go

现在假设我只想在//pq.go import ("container/heap") type PriorityQueue []*Vertex func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { ... } func (pq PriorityQueue) Swap(i, j int) { ... } func (pq *PriorityQueue) Push(x interface{}) { ... } func (pq *PriorityQueue) Pop() interface{} { ... } 中对此命名为MaxPQ的Tiny变体,在这里我想覆盖maxpq.go的单个实现细节,例如,覆盖{ {1}}。在不从字面上复制最后一个文件,更改类型名称和更改单个功能(例如pq.go的实现)的情况下如何实现?

意思是,有没有办法对与另一个非常相似的接口进行新的实现?

这样做,实际上是将其复制过来,似乎很麻烦,并且需要在多个地方进行更改:

Less(..)

2 个答案:

答案 0 :(得分:1)

有多种方法可以执行此操作。

您可以基于原始类型定义一个新类型,并委派所有方法:

type OriginalType struct {...}

func (o OriginalType) F() {...}

type NewType OriginalType

func (n NewType) F() { OriginalType(n).F() }

因此,您需要重新定义原始类型的所有方法,因为NewType不会“继承”原始类型的方法。

您可以嵌入:

type NewType struct {
   OldType
}

现在您有了NewType.F()函数,但是它将在NewType的OldType部分上运行。如果要重新声明,可以:

func (n NewType) F() { 
   n.OldType.F(); 
   // Do more stuff
}

如果您通过接口传递任何一个实例,它将像继承一样工作。那就是:

type IntF interface {
   F()
}

func f(v IntF) {
  v.F()
}

如果传递NewType,则将调用NewType.F。

但是,您必须传递一个接口,而不能传递嵌入式结构来获得封闭对象的行为:

func f(v OriginalType) {
   v.F()
}

func main() {
   n:=NewType()
   // f(n) Won't work
   f(n.OriginalType)

上面,仅将n的OriginalType部分发送到函数f,然后将调用OriginalType.F。

答案 1 :(得分:0)

您可以使用合成方法尝试类似的操作。

type iTemp interface {
    func1()
    func2()
}

type base struct {
}

func (base) func1() {
    fmt.Println("base func1")
}
func (base) func2() {
    fmt.Println("base func2")
}


type child struct {
    base
}

func (child) func1() {
    fmt.Println("child func1")
}

func main(){
    printMessage(base{})
    printMessage(child{})
}

func printMessage(t iTemp) {
    t.func1()
    t.func2()
}

输出:

base func1  
base func2  
child func1  
base func2  

在子结构中,您正在提供基类的func1函数的新实现,但是您仍然可以访问基类的实现,仍然可以使用child{}.base.func1()

对其进行调用