设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间23 现在时间23 缓存数据 荣耀也罢,屈辱也罢,都要以平和的心态去面对,少一些无奈与感慨,多一份从容和淡然。晚安!

荣耀也罢,屈辱也罢,都要以平和的心态去面对,少一些无奈与感慨,多一份从容和淡然。晚安!

查看: 1075|回复: 2

golang 接口嵌套实现复用的操作

[复制链接]

  离线 

TA的专栏

  • 打卡等级:即来则安
  • 打卡总天数:27
  • 打卡月天数:0
  • 打卡总奖励:366
  • 最近打卡:2025-08-19 21:15:33
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
353
主题
331
精华
0
金钱
1431
积分
744
注册时间
2023-2-10
最后登录
2025-8-29

发表于 2023-4-17 16:37:26 | 显示全部楼层 |阅读模式
大家还是直接看代码吧~
  1. package main
  2. import (
  3.     "fmt"
  4. )
  5. func main() {
  6.     start(NewB(C{}))
  7.     start(NewB(D{}))
  8. }
  9. type A interface {
  10.     what()
  11. }
  12. type B struct {
  13.     A
  14. }
  15. type C struct {
  16. }
  17. func (b C) what() {
  18.     fmt.Println("this is type C")
  19. }
  20. type D struct {
  21. }
  22. func (b D) what() {
  23.     fmt.Println("this is type D")
  24. }
  25. func start(b B) {
  26.     b.what()
  27. }
  28. func NewB(a A) B {
  29.     return B{a}
  30. }
复制代码
补充:【玩转Golang】通过组合嵌入实现代码复用
应用开发中的一个常见情景,为了避免简单重复,需要在基类中实现共用代码,着同样有助于后期维护。
如果在以往的支持类继承的语言中,比如c++,Java,c#等,这很简单!可是go不支持继承,只能mixin嵌入
且看下面的代码:
  1. type ManKind interface{
  2.     Say(s string);   
  3.     GetMouth()string
  4. }
  5. type Man struct{
  6.    
  7. }
  8. func NewMan() ManKind{
  9.     return &Man{};
  10. }
  11. func (this *Man)GetMouth()string{
  12.     return "M0"
  13. }
  14. func (this *Man) Say(s string){
  15.     fmt.Printf("\n Speak with mouth[%s] : "%s"",this.GetMouth(),s);
  16. }
  17. type StrongMan struct{
  18.     Man
  19. }
  20. func NewStrongMan()ManKind{
  21.     return &StrongMan{}
  22. }
  23. func (this*StrongMan)GetMouth()string{
  24.     return "M1"
  25. }
  26. func main(){   
  27.     NewMan().Say("good luck!")
  28.     NewStrongMan().Say("good luck!")
  29. }
复制代码
如果支持继承,很明显应该输出
  1. Speak with mouth[M0] : "good luck!"
  2. Speak with mouth[M1] : "good luck!"
复制代码
但是在golang中只能输出:
  1. Speak with mouth[M0] : "good luck!"
  2. Speak with mouth[M0] : "good luck!"
复制代码
StrongMan中调用Say(),此时可以将指针传递到内嵌类,只是简单的指向了Man的方法,在ManKind中调用GetMouth就是ManKind自己的GetMouth,和StrongMan没有关系。
当然,我们可以在StrongMan中覆盖Say方法
  1. func (this *StrongMan)Say(s string){
  2.     fmt.Printf("\n Speak with mouth[%s] : "%s"",this.GetMouth(),s);
  3. }
复制代码
此时,当然可以正确输出,因为本来调用的就都是StrongMan自己的方法了,这又和我们的初衷相违背了。那么这种情况怎么实现呢?我的方法是,让Man再脏一点儿,把需要的东西传递给组合进来的类。
给Man增加一个属性mouth,增加一个SetMouth方法,修改一下GetMouth方法,StrongMan的GetMouth方法删除掉,再修改一下NewStrongMan方法
最后的代码如下:
  1. package main
  2. import(
  3.     "fmt"
  4. )
  5. type ManKind interface{
  6.     Say(s string);   
  7.     SetMouth(m string)
  8.     GetMouth()string
  9. }
  10. type Man struct{
  11.     ManKind   
  12.     mouth string
  13. }
  14. func NewMan() ManKind{
  15.     return &Man{mouth:"M0"};
  16. }
  17. func (this *Man)GetMouth()string{
  18.     return this.mouth;
  19. }
  20. func (this *Man)SetMouth(s string){
  21.     this.mouth=s;
  22. }
  23. func (this *Man) Say(s string){
  24.     fmt.Printf("\n Speak with mouth[%s] : "%s"",this.GetMouth(),s);
  25. }
  26. type StrongMan struct{
  27.     Man
  28. }
  29. func NewStrongMan()ManKind{
  30.     sm := &StrongMan{}
  31.   sm.SetMouth("M1");
  32.   return sm;
  33. }
  34.    
  35. func main(){   
  36.     NewMan().Say("good luck!")
  37.     &NewStrongMan().Say("good luck!")
  38. }
复制代码
当然,如果你不愿意用Get、Set方法,也可以直接输出Man的Mouth属性。
我总结的嵌入式编程要点:

1,被嵌入的类的方法,只能访问他自己的字段,包装类即时声明了同名字段也没用。
2,包装类可以覆盖嵌入类的方法,但是嵌入类访问不到,亦然访问自己的方法。只能在包装类中连同调用方法一同实现。
3,包装类覆盖嵌入类字段后,亦然可以通过嵌入类的类名访问嵌入类的字段。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持晓枫资讯。如有错误或未考虑完全的地方,望不吝赐教。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:常驻代表
  • 打卡总天数:31
  • 打卡月天数:0
  • 打卡总奖励:399
  • 最近打卡:2025-10-24 17:19:15
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
1
主题
2
精华
0
金钱
457
积分
65
注册时间
2023-1-10
最后登录
2025-10-24

发表于 2023-5-29 22:15:10 | 显示全部楼层
感谢楼主分享~~~~~
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
15
积分
10
注册时间
2022-12-25
最后登录
2022-12-25

发表于 2025-11-9 05:01:26 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表