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中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 Golang
Golang 使用Map实现去重与set的功能操作
Apr 29 Golang
golang 实现Location跳转方式
May 02 Golang
golang中的并发和并行
May 08 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
Go 语言结构实例分析
Jul 04 Golang
Golang 链表的学习和使用
Apr 19 Golang
Golang 并发编程 SingleFlight模式
Apr 26 Golang
Golang解析JSON对象
Apr 30 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 异步执行方法,模拟多线程的应用分析
2013/06/03 PHP
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
关于PHP堆栈与列队的学习
2013/06/21 PHP
从PHP $_SERVER相关参数判断是否支持Rewrite模块
2013/09/26 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
2017/05/08 PHP
php实现用户注册密码的crypt加密
2017/06/08 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
JS自动缩小超出大小的图片
2012/10/12 Javascript
js 使用form表单select类实现级联菜单效果
2012/12/19 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
解析javascript 数组以及json元素的添加删除
2013/06/26 Javascript
解决node-webkit 不支持html5播放mp4视频的方法
2015/03/11 Javascript
Sea.JS知识总结
2016/05/05 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
深入理解bootstrap框架之第二章整体架构
2016/10/09 Javascript
微信小程序用户自定义模版用法实例分析
2017/11/28 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
详解Webpack + ES6 最新环境搭建与配置
2018/06/04 Javascript
vue打包相关细节整理(小结)
2018/09/28 Javascript
js实现简单模态框实例
2018/11/16 Javascript
vue指令做滚动加载和监听等
2019/05/26 Javascript
vue使用websocket的方法实例分析
2019/06/22 Javascript
JavaScript中BOM对象原理与用法分析
2019/07/09 Javascript
[01:04:14]VP vs TNC 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python 开发的三种运行模式详细介绍
2017/01/18 Python
python tools实现视频的每一帧提取并保存
2020/03/20 Python
redis数据库及与python交互用法简单示例
2019/11/01 Python
python set集合使用方法解析
2019/11/05 Python
python二维图制作的实例代码
2020/12/03 Python
英国最受欢迎的平价女士时装零售商:Roman Originals
2019/11/02 全球购物
采购员岗位职责
2013/11/15 职场文书
信息合作协议书
2014/10/09 职场文书
教师批评与自我批评心得体会
2014/10/16 职场文书
安全生产标语口号
2015/12/26 职场文书
Lombok的详细使用及优缺点总结
2021/07/15 Java/Android
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python