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 实现两个结构体复制字段
Apr 28 Golang
golang 比较浮点数的大小方式
May 02 Golang
浅谈golang 中time.After释放的问题
May 05 Golang
解决golang 关于全局变量的坑
May 06 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
Go中的条件语句Switch示例详解
Aug 23 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Golang MatrixOne使用介绍和汇编语法
Apr 19 Golang
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 Golang
Golang 入门 之url 包
May 04 Golang
Golang实现可重入锁的示例代码
May 25 Golang
Go微服务项目配置文件的定义和读取示例详解
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&&mysql)五
2006/10/09 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
javaScript同意等待代码实现心得
2011/01/01 Javascript
JavaScript仿静态分页实现方法
2015/08/04 Javascript
js操作table元素实现表格行列新增、删除技巧总结
2015/11/18 Javascript
让DIV的滚动条自动滚动到最底部的3种方法(推荐)
2016/09/24 Javascript
jQuery Datatable 多个查询条件自定义提交事件(推荐)
2017/08/24 jQuery
node+koa实现数据mock接口的方法
2017/09/20 Javascript
zTree 树插件实现全国五级地区点击后加载的示例
2018/02/05 Javascript
vue+springboot实现项目的CORS跨域请求
2018/09/05 Javascript
vue+element 模态框表格形式的可编辑表单实现
2019/06/07 Javascript
vue 源码解析之虚拟Dom-render
2019/08/26 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
使用uni-app开发微信小程序的实现
2019/12/13 Javascript
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
qpython3 读取安卓lastpass Cookies
2016/06/19 Python
详解Python开发中如何使用Hook技巧
2017/11/01 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
Python range、enumerate和zip函数用法详解
2019/09/11 Python
python线程信号量semaphore使用解析
2019/11/30 Python
Python实现变声器功能(萝莉音御姐音)
2019/12/05 Python
CSS3 简写animation
2012/05/10 HTML / CSS
AmazeUI 手机版页面的顶部导航条Header与侧边导航栏offCanvas的示例代码
2020/08/19 HTML / CSS
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
绢花、人造花和人造花卉:BLOOM
2019/08/07 全球购物
经济实惠的名牌太阳镜和眼镜:Privé Revaux
2021/02/07 全球购物
环境科学专业个人求职信
2013/09/26 职场文书
《路旁的橡树》教学反思
2014/04/07 职场文书
党的群众教育实践活动实施方案
2014/06/12 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
义诊活动通知
2015/04/24 职场文书
Django实现翻页的示例代码
2021/05/24 Python
SQL CASE 表达式的具体使用
2022/03/21 SQL Server