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语言操作数据库及其常规操作的示例代码
Apr 21 Golang
go:垃圾回收GC触发条件详解
Apr 24 Golang
用golang如何替换某个文件中的字符串
Apr 25 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
解决golang在import自己的包报错的问题
Apr 29 Golang
解决go在函数退出后子协程的退出问题
Apr 30 Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 Golang
go语言中http超时引发的事故解决
Jun 02 Golang
Go语言基础知识点介绍
Jul 04 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
Golang 对es的操作实例
Apr 20 Golang
Golang 结构体数据集合
Apr 22 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中XMLHttpRequest(Ajax)不能设置自定义的Referer的解决方法
2011/11/26 PHP
PHP文件上传处理案例分析
2016/10/15 PHP
微信公众号之主动给用户发送消息功能
2019/06/22 PHP
jquery 插件学习(二)
2012/08/06 Javascript
JS过滤url参数特殊字符的实现方法
2013/12/24 Javascript
js触发onchange事件的方法说明
2014/03/08 Javascript
JS取得绝对路径的实现代码
2015/01/16 Javascript
浅谈JavaScript中的作用域和闭包问题
2015/07/07 Javascript
关于jQuery中fade(),show()起始位置的一点小发现
2017/04/25 jQuery
微信小程序后台解密用户数据实例详解
2017/06/28 Javascript
微信小程序开发animation心跳动画效果
2017/08/16 Javascript
React Router v4 入坑指南(小结)
2018/04/08 Javascript
JavaScript对象拷贝与Object.assign用法实例分析
2018/06/20 Javascript
jQuery实现ajax回调函数带入参数的方法示例
2018/06/26 jQuery
小程序实现单选多选功能
2018/11/04 Javascript
vue请求服务器数据后绑定不上的解决方法
2019/10/30 Javascript
Vue结合路由配置递归实现菜单栏功能
2020/06/16 Javascript
python实现批量转换文件编码(批转换编码示例)
2014/01/23 Python
python处理文本文件并生成指定格式的文件
2014/07/31 Python
python中实现php的var_dump函数功能
2015/01/21 Python
python条件变量之生产者与消费者操作实例分析
2017/03/22 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
Python3调用百度AI识别图片中的文字功能示例【测试可用】
2019/03/13 Python
Python Web框架之Django框架文件上传功能详解
2019/08/16 Python
Python3直接爬取图片URL并保存示例
2019/12/18 Python
python使用Geany编辑器配置方法
2020/02/21 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
Python dict的常用方法示例代码
2020/06/23 Python
皮姆斯勒语言学习:Pimsleur Language Programs
2018/06/30 全球购物
伦敦一家领先的精品零售商:IRIS Fashion
2019/05/24 全球购物
中专自我鉴定
2014/02/05 职场文书
2014五年级班主任工作总结
2014/12/05 职场文书
《倍数和因数》教学反思
2016/02/23 职场文书
python设置 matplotlib 正确显示中文的四种方式
2021/05/10 Python
Python与C++中梯度方向直方图的实现
2022/03/17 Python
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL