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语言使用select{}阻塞main函数介绍
Apr 25 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
golang中的空slice案例
Apr 27 Golang
golang 如何用反射reflect操作结构体
Apr 28 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
Go timer如何调度
Jun 09 Golang
golang实现一个简单的websocket聊天室功能
Oct 05 Golang
实现GO语言对数组切片去重
Apr 20 Golang
Golang 切片(Slice)实现增删改查
Apr 22 Golang
Golang 实现WebSockets
Apr 24 Golang
Go调用Rust方法及外部函数接口前置
Jun 14 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新手上路(四)
2006/10/09 PHP
PHP循环获取GET和POST值的代码
2008/04/09 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
PHP+Ajax验证码验证用户登录
2016/07/20 PHP
PHP递归删除多维数组中的某个值
2017/04/17 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
JS字符串拼接在ie中都报错的解决方法
2014/03/27 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
javascript截取字符串小结
2015/04/28 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
2016/01/26 Javascript
老生常谈JavaScript中的this关键字
2016/10/01 Javascript
windows下vue.js开发环境搭建教程
2017/03/20 Javascript
基于input动态模糊查询的实现方法
2017/12/12 Javascript
JS中移除非数字最多保留一位小数
2018/05/09 Javascript
微信小程序页面传多个参数跳转页面的实现方法
2019/05/17 Javascript
nodejs+koa2 实现模仿springMVC框架
2020/10/21 NodeJs
python sys模块sys.path使用方法示例
2013/12/04 Python
从零学Python之入门(四)运算
2014/05/27 Python
Python多进程同步Lock、Semaphore、Event实例
2014/11/21 Python
Python图算法实例分析
2016/08/13 Python
Django中ORM表的创建和增删改查方法示例
2017/11/15 Python
python numpy 一维数组转变为多维数组的实例
2018/07/02 Python
预订全球最佳旅行体验:Viator
2018/03/30 全球购物
YII2 全局异常处理深入讲解
2021/03/24 PHP
硕士研究生自我鉴定范文
2013/12/27 职场文书
迟到检讨书800字
2014/01/13 职场文书
大学生的自我鉴定范文
2014/01/21 职场文书
中餐厅经理岗位职责
2014/04/11 职场文书
培训协议书范本
2014/04/22 职场文书
大队委竞选演讲稿
2014/04/28 职场文书
2014党的群众路线教育实践活动总结材料
2014/10/31 职场文书
2014个人年终工作总结范文
2014/12/15 职场文书
2015年组织部工作总结
2015/04/03 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书