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


Posted in Golang onApril 29, 2021

大家还是直接看代码吧~

package main
import (
    "fmt"
)
func main() {
    start(NewB(C{}))
    start(NewB(D{}))
}
type A interface {
    what()
}
type B struct {
    A
}
type C struct {
}
func (b C) what() {
    fmt.Println("this is type C")
}
type D struct {
}
func (b D) what() {
    fmt.Println("this is type D")
}
func start(b B) {
    b.what()
}
func NewB(a A) B {
    return B{a}
}

补充:【玩转Golang】通过组合嵌入实现代码复用

应用开发中的一个常见情景,为了避免简单重复,需要在基类中实现共用代码,着同样有助于后期维护。

如果在以往的支持类继承的语言中,比如c++,Java,c#等,这很简单!可是go不支持继承,只能mixin嵌入

且看下面的代码:

type ManKind interface{
    Say(s string);   
    GetMouth()string
}
type Man struct{
   
}
func NewMan() ManKind{
    return &Man{};
}
func (this *Man)GetMouth()string{
    return "M0"
}
func (this *Man) Say(s string){
    fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}
type StrongMan struct{
    Man
}
func NewStrongMan()ManKind{
    return &StrongMan{}
}
func (this*StrongMan)GetMouth()string{
    return "M1"
}
func main(){    
    NewMan().Say("good luck!")
    NewStrongMan().Say("good luck!")
}

如果支持继承,很明显应该输出

Speak with mouth[M0] : "good luck!"

Speak with mouth[M1] : "good luck!"

但是在golang中只能输出:

Speak with mouth[M0] : "good luck!"

Speak with mouth[M0] : "good luck!"

StrongMan中调用Say(),此时可以将指针传递到内嵌类,只是简单的指向了Man的方法,在ManKind中调用GetMouth就是ManKind自己的GetMouth,和StrongMan没有关系。

当然,我们可以在StrongMan中覆盖Say方法

func (this *StrongMan)Say(s string){
    fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}

此时,当然可以正确输出,因为本来调用的就都是StrongMan自己的方法了,这又和我们的初衷相违背了。那么这种情况怎么实现呢?我的方法是,让Man再脏一点儿,把需要的东西传递给组合进来的类。

给Man增加一个属性mouth,增加一个SetMouth方法,修改一下GetMouth方法,StrongMan的GetMouth方法删除掉,再修改一下NewStrongMan方法

最后的代码如下:

package main
import(
    "fmt"
)
type ManKind interface{
    Say(s string);    
    SetMouth(m string)
    GetMouth()string
}
type Man struct{
    ManKind    
    mouth string
}
func NewMan() ManKind{
    return &Man{mouth:"M0"};
}
func (this *Man)GetMouth()string{
    return this.mouth;
}
func (this *Man)SetMouth(s string){
    this.mouth=s;
}
func (this *Man) Say(s string){
    fmt.Printf("\n Speak with mouth[%s] : \"%s\"",this.GetMouth(),s);
}
type StrongMan struct{
    Man
}
func NewStrongMan()ManKind{
    sm := &StrongMan{}
  sm.SetMouth("M1");
  return sm;
}
    
func main(){    
    NewMan().Say("good luck!")
    &NewStrongMan().Say("good luck!")
}

当然,如果你不愿意用Get、Set方法,也可以直接输出Man的Mouth属性。

我总结的嵌入式编程要点:

1,被嵌入的类的方法,只能访问他自己的字段,包装类即时声明了同名字段也没用。

2,包装类可以覆盖嵌入类的方法,但是嵌入类访问不到,亦然访问自己的方法。只能在包装类中连同调用方法一同实现。

3,包装类覆盖嵌入类字段后,亦然可以通过嵌入类的类名访问嵌入类的字段。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
Go语言使用select{}阻塞main函数介绍
Apr 25 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
golang中切片copy复制和等号复制的区别介绍
Apr 27 Golang
解决Golang中ResponseWriter的一个坑
Apr 27 Golang
golang 比较浮点数的大小方式
May 02 Golang
golang中字符串MD5生成方式总结
Jul 04 Golang
Go语言实现Base64、Base58编码与解码
Jul 26 Golang
golang生成并解析JSON
Apr 14 Golang
Golang 遍历二叉树
Apr 19 Golang
Golang并发工具Singleflight
May 06 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 #Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 #Golang
Golang 空map和未初始化map的注意事项说明
彻底理解golang中什么是nil
基于Go Int转string几种方式性能测试
Apr 28 #Golang
Go语言中break label与goto label的区别
golang 如何用反射reflect操作结构体
Apr 28 #Golang
You might like
PHP在字符断点处截断文字的实现代码
2011/04/21 PHP
CodeIgniter上传图片成功的全部过程分享
2013/08/12 PHP
php根据年月获取季度的方法
2014/03/31 PHP
php中switch与ifelse的效率区别及适用情况分析
2015/02/12 PHP
PHP 获取指定地区的天气实例代码
2017/02/08 PHP
php实现数字补零的方法总结
2018/09/12 PHP
利用js实现前台动态添加文本框,后台获取文本框内容(示例代码)
2013/11/25 Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
2014/11/04 Javascript
纯js实现重发验证码按钮倒数功能
2015/04/21 Javascript
jQuery+Ajax实现用户名重名实时检测
2017/06/01 jQuery
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
React-Native中props具体使用详解
2017/09/04 Javascript
微信小程序项目实践之九宫格实现及item跳转功能
2018/07/19 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
微信小程序实现简单的select下拉框
2020/11/23 Javascript
Python解释执行原理分析
2014/08/22 Python
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
2015/03/19 Python
Python2.7读取PDF文件的方法示例
2017/07/13 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
django主动抛出403异常的方法详解
2019/01/04 Python
Django异步任务之Celery的基本使用
2019/03/23 Python
Django使用Channels实现WebSocket的方法
2019/07/28 Python
Django 用户登陆访问限制实例 @login_required
2020/05/13 Python
实例讲解利用HTML5 Canvas API操作图形旋转的方法
2016/03/22 HTML / CSS
Html5在手机端调用相机的方法实现
2020/05/13 HTML / CSS
创建学习型党组织实施方案
2014/03/29 职场文书
大二学习计划书范文
2014/04/27 职场文书
入职担保书怎么写
2014/05/12 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
西游降魔篇观后感
2015/06/15 职场文书
早安问候语大全
2015/11/10 职场文书
Mysql服务添加 iptables防火墙策略的方案
2021/04/29 MySQL
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android