go - go 如何强制多态性使用子方法?
问题描述
我来自像 C++ 这样的语言,其中 OOP 定义明确并且通常使用多态性。我是使用 Go 的新手,我试图从多态中调用子方法,但我不知道什么是正确的模式。
如您所见,我创建了两个结构,并定义了 2 个方法 fun1 和 fun2,在基结构中我只覆盖其中一个,而在父结构中我正在调用它。如果多态性是正确的,应该调用这个子方法,至少在我的例子中,这不会发生
这是代码:
package main
import (
"fmt"
)
type A struct {
}
type B struct {
A
}
func (a* A) fun1() {
fmt.Println("I'm in A.fun1()")
a.fun2()
}
func (a* A) fun2() {
fmt.Println("I'm in A.fun2()")
}
func (b* B) fun2() {
fmt.Println("I'm in B.fun2()")
}
func main() {
b := B{}
b.fun1()
}
你可以在这里试试:https: //play.golang.org/p/s7xZun-6Otx
输出是
I'm in A.fun1()
I'm in A.fun2()
我被预料到了
I'm in A.fun1()
I'm in B.fun2()
我怎样才能做到这一点?在 Go 中为此进行良好设计的正确方法是什么?
问候
解决方案
Go 对象通常是围绕组合而不是继承构建的,因为您使用的模式会使结构很难对正在做A
什么做出任何假设fun2
。go 中的多态性是在接口级别完成的。首选方法是将“可覆盖”fun2
功能拉入一个单独的接口类型,该接口类型被传递给fun1
函数或存储在包含fun1
. 如果没有具体说明您将如何执行此操作,则很难做出合理的示例,但这是模式:
package main
import (
"fmt"
)
type fun2er interface {
fun2()
}
type A struct {
B fun2er
}
func (a* A) fun1() {
fmt.Println("I'm in A.fun1()")
a.B.fun2()
}
type B1 struct {}
func (b B1) fun2() {
fmt.Println("I'm in B1.fun2()")
}
type B2 struct {}
func (b B2) fun2() {
fmt.Println("I'm in B2.fun2()")
}
func main() {
a1 := A{B: B1{}}
a2 := A{B: B2{}}
a1.fun1()
a2.fun1()
}
这将打印:
I'm in A.fun1()
I'm in B1.fun2()
I'm in A.fun1()
I'm in B2.fun2()
编辑:
我想为它在引擎盖下的工作原理添加更多颜色。您“扩展”您的A
类型的B
方式称为结构嵌入,并且主要是用于添加与其类型相同B
的类型的字段的语法糖:A
type A struct {}
type B struct {
A A
}
主要区别在于,当使用结构嵌入时,您可以A
直接在B
对象上调用方法b.fun1()
。调用 thisa
时,传递给的类似 this 的参数fun1
不是整个B
对象,而只是其中的A
字段(就像您调用了一样b.A.fun1()
),这就是为什么fun1
调用时fun2
,它正在调用A
实现,因为它没有访问权限到B
它存储在里面的对象。
推荐阅读
- reactjs - 如何使用 webpack 分别捆绑供应商和主脚本?
- mysql - 获取 mysql.connector.errors.ProgrammingError: 1045 (28000): Access denied for user 'vsearch'@'localhost' (using password: YES) with python
- javascript - JS数组合并求和
- javascript - 有没有一种方便的方法来引用 Svelte 组件中的 DOM 元素?
- javascript - 如何显示用户选择上传的图像
- java - Java 中循环技巧的 Helloworld 示例
- c++ - 从 txt 文件中删除注释
- ios - 如何在 UITableView 中执行网络调用
- spring - 如何使用 Spring Boot 资源服务器拥有未经身份验证的端点
- python - 如何在 Python 中读取和写入 config.ini 文件?