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 相关文章推荐
golang判断key是否在map中的代码
Apr 24 Golang
Go语言切片前或中间插入项与内置copy()函数详解
Apr 27 Golang
golang 接口嵌套实现复用的操作
Apr 29 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
golang slice元素去重操作
Apr 30 Golang
Golang生成Excel文档的方法步骤
Jun 09 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 Golang
Go 通过结构struct实现接口interface的问题
Oct 05 Golang
Golang 并发下的问题定位及解决方案
Mar 16 Golang
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 Golang
Python测试框架pytest核心库pluggy详解
Aug 05 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面向对象全攻略 (三)特殊的引用“$this”的使用
2009/09/30 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
PHP产生不重复随机数的5个方法总结
2014/11/12 PHP
ECSHOP在PHP5.5及高版本上报错的解决方法
2015/08/31 PHP
深入浅析PHP7.0新特征(五大新特征)
2015/10/29 PHP
php把文件设置为插件的技巧方法
2020/02/03 PHP
js数字输入框(包括最大值最小值限制和四舍五入)
2009/11/24 Javascript
js调用打印机打印网页字体总是缩小一号的解决方法
2014/01/24 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
函数window.open实现关闭所有的子窗口
2015/08/03 Javascript
基于js实现微信发送好友如何分享到朋友圈、微博
2015/11/30 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
2016/12/28 Javascript
JS查找英文文章中出现频率最高的单词
2017/03/20 Javascript
JS实现加载和读取XML文件的方法详解
2017/04/24 Javascript
详解nodeJS之路径PATH模块
2017/05/31 NodeJs
Vue 2.0的数据依赖实现原理代码简析
2017/07/10 Javascript
three.js中文文档学习之如何本地运行详解
2017/11/20 Javascript
微信小程序实现简单input正则表达式验证功能示例
2017/11/30 Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
2018/07/03 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
jQuery实现高度灵活的表单验证功能示例【无UI】
2020/04/30 jQuery
vue项目在webpack2实现移动端字体自适配功能
2020/06/02 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
2020/08/22 Javascript
Python多线程实现同步的四种方式
2017/05/02 Python
Python Socket编程之多线程聊天室
2018/07/28 Python
深入了解和应用Python 装饰器 @decorator
2019/04/02 Python
PyQt5事件处理之定时在控件上显示信息的代码
2020/03/25 Python
Python新手学习标准库模块命名
2020/05/29 Python
雪花秀美国官方网站:韩国著名草本护肤化妆品品牌
2016/10/19 全球购物
美国家居装饰店:Z Gallerie
2020/12/28 全球购物
总监职责范文
2013/11/09 职场文书
七年级音乐教学反思
2014/01/26 职场文书
写作技巧:如何撰写一份优秀的营销策划书
2019/08/13 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
Python+SeaTable实现计算两个日期间的工作日天数
2022/07/07 Python
基于Redission的分布式锁实战
2022/08/14 Redis