实现出来是这个样子,接受各位 Gopher 的批判
package main
import "fmt"
// Require 必须要子类实现的方法
// 对应 abstract method
type Require interface {
Require()
}
// Hook 可能会被子类重写的方法
type Hook interface {
Require
Test1()
Test2()
}
// IBase 类似 Java 的 interface -> abstract class -> sub class 套娃
type IBase interface {
Hook
Common()
}
// Base abstract class
type Base[T Hook] struct {
hook T
}
func NewBase[T Hook](hook T) *Base[T] {
res := &Base[T]{
hook: hook,
}
return res
}
func (b *Base[T]) Common() {
b.hook.Require()
b.hook.Test2()
b.hook.Test1()
}
func (*Base[T]) Test1() {
fmt.Println("Base.Test1")
}
func (*Base[T]) Test2() {
fmt.Println("Base.Test2")
}
// Sub 抽象类的子类
type Sub struct {
*Base[*Sub]
}
func NewSub() *Sub {
res := &Sub{}
// 注意 %v 输出可能会有套娃死循环
res.Base = NewBase[*Sub](res)
return res
}
// Test1 复用 Base 的 Test1
//func (*Sub) Test1() {
// fmt.Println("Sub.Test1")
//}
// Test2 重写 Base 的 Test2
func (*Sub) Test2() {
fmt.Println("Sub.Test2")
}
// Require 必须要子类实现的 Require 不写会编译报错
func (*Sub) Require() {
fmt.Println("Sub.Require")
}
func main() {
m := make(map[int]IBase)
m[1] = NewSub()
b := m[1]
b.Common()
/*
Output:
Sub.Require
Sub.Test2
Base.Test1
*/
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.