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中semaphore(信号量)源码
Apr 03 Golang
Go语言带缓冲的通道实现
Apr 26 Golang
使用Golang的channel交叉打印两个数组的操作
Apr 29 Golang
Golang 编译成DLL文件的操作
May 06 Golang
go语言中http超时引发的事故解决
Jun 02 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
golang中的struct操作
Nov 11 Golang
Golang MatrixOne使用介绍和汇编语法
Apr 19 Golang
Golang 入门 之url 包
May 04 Golang
Go语言怎么使用变长参数函数
Jul 15 Golang
在ubuntu下安装go开发环境的全过程
Aug 05 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 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中将字符串转为HTML的实体引用的一个类
2013/02/03 PHP
使用php记录用户通过搜索引擎进网站的关键词
2014/02/13 PHP
PHP积分兑换接口实例
2015/02/09 PHP
功能强大的PHP图片处理类(水印、透明度、旋转)
2015/10/21 PHP
微信开发之获取JSAPI TICKET
2017/07/07 PHP
jQuery EasyUI API 中文文档 - ComboTree组合树
2011/10/11 Javascript
JavaScript作用域链使用介绍
2013/08/29 Javascript
JS实现保留n位小数的四舍五入问题示例
2016/08/03 Javascript
功能强大的Bootstrap组件(结合js)
2016/08/03 Javascript
基于jquery二维码生成插件qrcode
2017/01/07 Javascript
Vue 2.5.2下axios + express 本地请求404的解决方法
2018/02/21 Javascript
js使用formData实现批量上传
2020/03/27 Javascript
基于Express框架使用POST传递Form数据
2019/08/10 Javascript
学习 Vue.js 遇到的那些坑
2021/02/02 Vue.js
[01:06] DOTA2英雄背景故事第三期之秩序法则光之守卫
2020/07/07 DOTA
Python设计模式之观察者模式简单示例
2018/01/10 Python
详解python里的命名规范
2018/07/16 Python
几行Python代码爬取3000+上市公司的信息
2019/01/24 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
Windows 下python3.8环境安装教程图文详解
2020/03/11 Python
PageFactory设计模式基于python实现
2020/04/14 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
网页切图的CSS和布局经验与要点
2015/04/09 HTML / CSS
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
电子商务专业自我鉴定
2013/12/18 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
2014审计局领导班子民主生活会对照检查材料思想汇报
2014/09/20 职场文书
总经理检讨书范文
2015/02/16 职场文书
副总经理岗位职责范本
2015/04/08 职场文书
单位实习介绍信
2015/05/05 职场文书
校园音乐节目广播稿
2015/08/19 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书
如果用一句诗总结你的上半年,你会用哪句呢?
2019/07/16 职场文书
《LOL》“克隆大作战”久违归来 幻灵战队皮肤上线
2022/04/03 其他游戏