我想我一直在考虑针对以下问题的多态解决方案:
假设我有一个BaseTX struct
,其中包含用于交易的字段。现在,我有两种特殊的交易类型:RewardTX struct
和AllowanceTX struct
。
RewardTX struct
目前只有BaseTX struct
的组成。
AllowanceTX struct
由BaseTX struct
和AddField
组成。
我还有一个函数logicAndSaveTX()
,该函数在BaseTX
的字段中具有一些逻辑,但是最后是使用json.Marshal()
序列化整个对象并将byte[]
保存在某个地方
type TXapi interface {
logicAndSaveTX()
}
type BaseTX struct {
Field1 string
Field2 string
}
type RewardTX struct {
BaseTX
}
type AllowanceTX struct {
BaseTX
AddField string
}
func (tx BaseTX) logicAndSaveTX() {
// logic on BaseTX fields; simplified:
tx.Field1 = "overwritten"
tx.Field2 = "logic done"
// here would be marshal to json and save; simplified to print object:
fmt.Printf("saved this object: %+v \n", tx)
}
func SaveTX(tx TXapi) {
tx.logicAndSaveTX()
}
func main() {
rewardTX := RewardTX{BaseTX : BaseTX{Field1: "Base info1", Field2: "Base info2"}}
SaveTX(rewardTX) // should print rewardTX with fields from BaseTX
allowanceTX := AllowanceTX{BaseTX : BaseTX{Field1: "Base info1", Field2: "Base info2"}, AddField: "additional field"}
SaveTX(allowanceTX) // would like to print allowanceTX with fields from BaseTX + AdditionalField >>> instead only printing fields from BaseTX
}
https://play.golang.org/p/0Vu_YXktRIk
我试图弄清楚如何实现两种事务上的结构和功能,但是最后正确地序列化了这两种结构。我的问题是,在当前的实现中没有看到AddField
。
也许我在这里遇到了一些失灵-我真的很想以“正确的执行方式”实现这一目标。 :)
答案 0 :(得分:3)
Go不是面向对象的。 Go中多态的 only 形式是接口。
与其他面向对象的语言相比较可能会很困难,因为您必须摆脱可能要继承的许多想法,例如“基础”类/类型。只需从您的设计思路中删除“基础”即可;您正在尝试将合成转换为继承,这只会使您陷入麻烦。
在这种情况下,也许您在这里有合理的构图理由;您有一些通用的共享字段供多种类型使用,但这不是“基本”类型。可能是“元数据”之类的东西-考虑到您的示例非常抽象,我不能说该怎么称呼,但是您知道了。
所以也许你有
type TXapi interface {
logicAndSaveTX()
}
type Metadata struct {
Field1 string
Field2 string
}
type RewardTX struct {
Metadata
}
func (tx RewardTX) logicAndSaveTX() {
// logic on BaseTX fields; simplified:
tx.Field1 = "overwritten"
tx.Field2 = "logic done"
// here would be marshal to json and save; simplified to print object:
fmt.Printf("saved this object: %+v \n", tx)
}
type AllowanceTX struct {
Metadata
AddField string
}
func (tx AllowanceTX) logicAndSaveTX() {
// logic on BaseTX fields; simplified:
tx.Field1 = "overwritten"
tx.Field2 = "logic done"
tx.AddField = "more stuff"
// here would be marshal to json and save; simplified to print object:
fmt.Printf("saved this object: %+v \n", tx)
}
如果元数据(或其他任何内容)字段的使用在所有用途上都是相同的,则也许您可以给该类型使用其自己的logicTX
方法来填充这些字段,可以由logicAndSaveTX
调用嵌入它的结构。
这里的关键是考虑要被限定在该类型上的行为(方法),而不是将其视为能够对“子类型”进行操作。子类型不存在,并且嵌入的类型无法在其容器上进行操作。
答案 1 :(得分:0)
这里还要指出的是,Go仅通过接口支持运行时多态性。在Golang中不可能实现编译时多态。
来源:-https://golangbyexample.com/oop-polymorphism-in-go-complete-guide/