问题描述
如何在Go中实现抽象类?由于Go不允许我们在接口中包含字段,因此这将是一个无状态的对象.因此,换句话说,Go中的方法是否可以具有某种默认实现?
How to implement an abstract class in Go? As Go doesn't allow us to have fields in interfaces, that would be a stateless object. So, in other words, is it possible to have some kind of default implementation for a method in Go?
考虑一个例子:
type Daemon interface {
start(time.Duration)
doWork()
}
func (daemon *Daemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
daemon.doWork()
}
}()
}
type ConcreteDaemonA struct { foo int }
type ConcreteDaemonB struct { bar int }
func (daemon *ConcreteDaemonA) doWork() {
daemon.foo++
fmt.Println("A: ", daemon.foo)
}
func (daemon *ConcreteDaemonB) doWork() {
daemon.bar--
fmt.Println("B: ", daemon.bar)
}
func main() {
dA := new(ConcreteDaemonA)
dB := new(ConcreteDaemonB)
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
time.Sleep(100 * time.Second)
}
由于无法将接口用作接收器,因此无法编译.
This won't compile as it's not possible to use interface as a receiver.
事实上,我已经回答了我的问题(请参见下面的答案).但是,这是实现这种逻辑的惯用方式吗?除了语言的简单性之外,还有什么理由不使用默认实现?
In fact, I have already answered my question (see the answer below). However, is it an idiomatic way to implement such logic? Are there any reasons not to have a default implementation besides language's simplicity?
推荐答案
一个简单的解决方案是将daemon *Daemon
移至参数列表(从而从界面中删除start(...)
):
An easy solution is to move daemon *Daemon
to the argument list (thus removing start(...)
from the interface):
type Daemon interface {
// start(time.Duration)
doWork()
}
func start(daemon Daemon, duration time.Duration) { ... }
func main() {
...
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
...
}
这篇关于如何在Go中实现抽象类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!