go虚函数问题

fzy951 2017-02-20 08:18:09
//***test.go************************************************************
package main

import "fmt"

type StructA struct {
}

type StructB struct {
StructA
}

type StructInterface interface {
Foo()
Call()
}


func (s *StructA)Foo() {
fmt.Println("StructA")
}

func (s *StructB)Foo() {
fmt.Println("StructB")
}

func (s *StructA)Call() {
Call(s)
}

//func (s *StructB)Call() {
// Call(s)
//}

func Call(s StructInterface) {
s.Foo()
}


//*********main.go****************************************************************
package main
func main() {
var value StructInterface
value = new(StructB)
value.Foo()
value.Call()
}


//*********问题出来了******************************************
Call和Foo打印输出不一致!!!
Foo具有抽象接口概念,打印的是结构体B的值,
但Call调用的还是A的结果!!!这个在面向对象里是不正确的!

我想问的是谁有相应的解决方案啊?
...全文
2259 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
fwhezfwhez 2018-12-04
  • 打赏
  • 举报
回复
你在生产中也会产出这样的代码吗?
纯理论的代码在生产中是废品,不要深究了,浪费时间
qybao 2018-12-04
  • 打赏
  • 举报
回复
我的理解是
StructB没有实现Call方法,理论上应该不属于StructInterface接口类型
但是它包含了StructA,而StructA属于StructInterface接口类型,也就是StrcutB包含了StructInterface接口,所以调用StructInterface接口方法就会调用StrcutA的方法(如果StrcutB里没有StrcutA应该编译不过,因为没有实现StructInterface的方法,不属于StructInterface类型)
而StructB又实现了Foo,所以调用Foo自然就调用自己的Foo方法
leeing227 2018-03-15
  • 打赏
  • 举报
回复
人才,go里面有虚函数?
smmssmms 2017-12-26
  • 打赏
  • 举报
回复
func (s *StructA)Call() 实际参数压栈是 func Call(s *StructA)
昵称很不好取 2017-12-20
  • 打赏
  • 举报
回复
package main

import (
	"fmt"
)

type StructA struct {
}

type StructB struct {
	StructA
}

type StructInterface interface {
	Foo()
	Call()
}

func (s *StructA) Foo() {
	fmt.Println("StructA")
}

func (s *StructB) Foo() {
	fmt.Println("StructB")
}

func (s *StructA) Call() {
	Call(s)
}

func (s *StructB) Call() {
	Call(s)
}

func Call(s StructInterface) {
	s.Foo()
}

func main() {
	var value StructInterface
	value = new(StructB)
	value.Foo()
	value.Call()
}
上面代码里,structB实现了Foo和Call两个方法,所以,value.Foo()与value.Call()都会在B的scope里找到,输出两个structB,但是如何注释掉下面的代码
//func (s *StructB) Call() {
//	Call(s)
//}
那么B没有实现Call这个方法,会去它的子scope,也就是structA里面寻找,然后输出A的实现
Man_tou121 2017-12-20
  • 打赏
  • 举报
回复
go中没有虚函数吧
EvilWwwww 2017-11-26
  • 打赏
  • 举报
回复
我也碰到了这个问题怎么解决的
Cynhard85 2017-04-23
  • 打赏
  • 举报
回复
编译器在解析value.Call()的时候,回从实际类型(也就是StructB)出发,查找有没有Call这个方法,如果有则调用,如果没有,则查找StructB的字段有没有这个方法,如果有则调用,如果没有继续查找StructB的下一个字段,直到所有字段查找完毕。如果还是没有,则查找字段的字段有没有这个方法,依次类推。到最后如果还是没有,则报错。
不得闲 2017-03-07
  • 打赏
  • 举报
回复
Go中不存在虚函数的东西。
悲催的码农 2017-02-22
  • 打赏
  • 举报
回复
你要用面向对象的思维理解的话我觉得可以这样理解 A是父类 B是子类 B实现了Foo,但是没有实现Call A两个都实现了 那么B调用Foo的时候肯定是会走他自己的实现(这个没问题吧) 调用Call的时候B没有这个方法,转而去查询父类A,查到了,所以执行的是A的Call

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧