闽公网安备 35020302035485号
如题,Java仔想在 Go 中写类似 interface -> abstract class -> sub class 的玩意
实现出来是这个样子,接受各位 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
*/
}
简单版的代码就是:
```go type Worker interface { MustImplementStep() // 必须被实现的方法 OptionalHook() // 一个有默认行为的、可选的钩子方法 } type BaseWorker struct{} func (b *BaseWorker) OptionalHook() { fmt.Println("-> BaseWorker: 执行默认的钩子逻辑。") } type ConcreteWorker struct { BaseWorker // 嵌入“基类”,OptionalHook 的默认实现。 } // MustImplementStep 实现接口中必须被实现的方法 func (c *ConcreteWorker) MustImplementStep() { fmt.Println("-> ConcreteWorker: 执行必须实现的步骤。") } // 编译期安全检查,如果 ConcreteWorker 未实现 MustImplementStep (注释掉上面方法)会报错 var _ Worker = (*ConcreteWorker)(nil) // OptionalHook “重写”嵌入的钩子方法。 func (c *ConcreteWorker) OptionalHook() { fmt.Println("-> ConcreteWorker: 开始执行重写的钩子逻辑。") // super.method() c.BaseWorker.OptionalHook() fmt.Println("-> ConcreteWorker: 结束执行重写的钩子逻辑。") } func RunTemplate(w Worker) { fmt.Println("--- 模板开始 ---") w.MustImplementStep() w.OptionalHook() fmt.Println("--- 模板结束 ---") } func main() { worker := &ConcreteWorker{} RunTemplate(worker) } `````` package main import "fmt" // 定义 RouteStrategy 为一个接口,包含 CalculateTime 方法 type RouteStrategy interface { CalculateTime(origin, destination string) int } // 使用函数类型作为策略 type StrategyFunc func(origin, destination string) int // 实现 RouteStrategy 接口的 CalculateTime 方法 func (sf StrategyFunc) CalculateTime(origin, destination string) int { return sf(origin, destination) } // 实现三种策略:步行、骑行、驾车 func WalkStrategyFunc(origin, destination string) int { // 假设固定耗时 30 分钟 return 30 } func BikeStrategyFunc(origin, destination string) int { // 假设固定耗时 15 分钟 return 15 } func DriveStrategyFunc(origin, destination string) int { // 假设固定耗时 10 分钟 return 10 } // 路线规划器 type RoutePlanner struct { strategy RouteStrategy } // 设置策略 func (rp *RoutePlanner) SetStrategy(strategy RouteStrategy) { rp.strategy = strategy } // 估算出行时间 func (rp *RoutePlanner) EstimateTime(origin, destination string) int { return rp.strategy.CalculateTime(origin, destination) } func main() { planner := &RoutePlanner{} // 使用步行策略 walkStrategy := StrategyFunc(WalkStrategyFunc) planner.SetStrategy(walkStrategy) fmt.Println("Walk Time:", planner.EstimateTime("Home", "School")) // 使用骑行策略 bikeStrategy := StrategyFunc(BikeStrategyFunc) planner.SetStrategy(bikeStrategy) fmt.Println("Bike Time:", planner.EstimateTime("Home", "School")) // 使用驾车策略 driveStrategy := StrategyFunc(DriveStrategyFunc) planner.SetStrategy(driveStrategy) fmt.Println("Drive Time:", planner.EstimateTime("Home", "Work")) } ```-----
type Pusher func(track Track) error func PushToLog(track Track) error { slog.Infof("track: %+v", track) return nil } func NewMqttPusherAdapter(mqttPusher *MqttPusher) Pusher { return mqttPusher.Push }type IFIrst interface{ FirstFunc() } type ISecond interface{ SecondFunc() } type Entity struct{ } func (e *Entity)FirstFunc(){ print("first called") } func (e *Entity)SecondFunc(){ print("second called") } func main(){ var obj any obj = &Entity{} if first,ok:=obj.(IFirst);ok{ first.FirstFunc() } if second,ok:=obj.(ISecond);ok{ second.SecondFunc() } }好像官方是这么说的
接口是有必要的,继承是有害的。