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原生库的中bytes.Buffer用法
Apr 25 Golang
golang json数组拼接的实例
Apr 28 Golang
golang 如何通过反射创建新对象
Apr 28 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
使用golang编写一个并发工作队列
May 08 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
浅谈Go语言多态的实现与interface使用
Jun 16 Golang
Go语言设计模式之结构型模式
Jun 22 Golang
Go语言实现Base64、Base58编码与解码
Jul 26 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
Golang 链表的学习和使用
Apr 19 Golang
GoFrame框架数据校验之校验结果Error接口对象
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不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
详解json在php中的应用
2018/09/30 PHP
Laravel 5+ .env环境配置文件详解
2020/04/06 PHP
JavaScript 指导方针
2007/04/05 Javascript
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
推荐10个超棒的jQuery工具提示插件
2011/10/11 Javascript
在JavaScript中typeof的用途介绍
2013/04/11 Javascript
鼠标焦点离开文本框时验证的js代码
2013/07/19 Javascript
Javascript之this关键字深入解析
2013/11/12 Javascript
javascript的数组和常用函数详解
2014/05/09 Javascript
js 通过cookie实现刷新不变化树形菜单
2014/10/30 Javascript
JS实现的数组全排列输出算法
2015/03/19 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
2015/08/27 Javascript
JS表格组件神器bootstrap table使用指南详解
2017/04/12 Javascript
vue.js实现带日期星期的数字时钟功能示例
2018/08/28 Javascript
使用vue中的混入mixin优化表单验证插件问题
2019/07/02 Javascript
微信小程序后端无法保持session的原因及解决办法问题
2020/03/20 Javascript
python实现网页链接提取的方法分享
2014/02/25 Python
python实现逆波兰计算表达式实例详解
2015/05/06 Python
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
2015/10/18 Python
Python中operator模块的操作符使用示例总结
2016/06/28 Python
Python编程之event对象的用法实例分析
2017/03/23 Python
基于python 爬虫爬到含空格的url的处理方法
2018/05/11 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
PYTHON实现SIGN签名的过程解析
2019/10/28 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
TensorFlow实现从txt文件读取数据
2020/02/05 Python
python 回溯法模板详解
2020/02/26 Python
python实现拼接图片
2020/03/23 Python
Europcar德国:全球汽车租赁领域的领导者
2018/08/15 全球购物
英国最大的纸工艺品商店:CraftStash
2018/12/01 全球购物
教师自我鉴定范文
2014/03/20 职场文书
客户经理竞聘演讲稿
2014/05/15 职场文书
护士自我推荐信范文
2015/03/24 职场文书
详解nginx location指令
2022/01/18 Servers