Go语言无法天然支持继承,但是又想要实现面向对象的特性。
即父类对象 使用子类对象初始化,那么该父类对象调用的函数就是子类实现的函数 ,从而满足LSP(子类交换原则)。

案例一: Go语言 支持扩展父类的功能,如下代码:

package oriented_testimport ("fmt""testing"
)// Pet 类
type Pet struct {}func (p *Pet) Speak(){ // Pet类的函数成员fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) { // Pet类的函数成员p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 扩展Pet的功能
type Dog struct {p *Pet
}// 扩展父类的方法
func (d *Dog) Speak(){d.p.Speak()
}// 扩展父类的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {dog := new(Dog)dog.SpeakTo("Test dog")
}

以上测试代码的输出如下:

Pet speak.
Dog Speakto  Test dog

dog的SpeakTo中调用了dog 的Speak,其中调用了Pet的Speak,所以输出正常。
Pet 和 Dog调用不会相互影响,完全由用户决定。

但是这和我们所想需要的不同,Pet类有自己的方法,Dog类有自己的方法,两者作用域完全不同。
这里Go语言推出了匿名嵌套类型,即Dog类不用实现自己的和Pet类同名的方法即可,通过在Dog类的声明中变更Pet成员。

案例二: Go语言支持匿名函数类型

// Dog 扩展Pet的功能
type Dog struct {Pet
}

这样即不需要Dog声明自己的同名函数成员,默认的调用即为Pet成员函数的调用

package oriented_testimport ("fmt""testing"
)type Pet struct {}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 扩展Pet的功能
type Dog struct {Pet // 支持匿名嵌套类型,
}func TestDog(t *testing.T) {var dog Dogdog.Speak()dog.SpeakTo("Test dog")
}

最终的输出如下:

=== RUN   TestDog
Pet speak.
Pet speak.
Pet SpeakTo  Test dog
--- PASS: TestDog (0.00s)

调用的都是Pet的成员函数,感觉像是继承了,因为继承默认就是子类能够使用父类的公有成员。
在匿名嵌套类型下,我们想要完整尝试一下Go语言是否真正支持继承,可以像之前的代码一样在Dog中实现Pet的同名函数,且能够通过父类对象调用子类的成员方法,像C++/Java这样进行向上类型转换(本身是不可能的,Go语言不支持显式类型转换)。
案例三: Go语言不支持继承,如下代码:

package oriented_testimport ("fmt""testing"
)type Pet struct {}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 扩展Pet的功能
type Dog struct {//p *PetPet // 支持匿名嵌套类型
}// 重载父类的方法
func (d *Dog) Speak(){fmt.Print("Dog speak.\n")
}// 重载父类的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {var dog Pet = new(Dog)dog.Speak()dog.SpeakTo("Test dog")
}

在最后的输出会编译出错,不支持将Pet类型转换为Dog类型:

./oriented_test.go:38:6: cannot use new(Dog) (type *Dog) as type Pet in assignment

总结一下,Go语言并不支持继承,能够支持接口的扩展 和 复用(匿名嵌套类型)

其中扩展 就是不同类实现相同的成员函数,能够实现类似于案例一中的扩展接口形态。
复用则是通过匿名嵌套类型实现 类似于重载的功能,可以看看案例二的代码。

Go 分布式学习利器(12)-- Go语言的扩展和复用相关推荐

  1. Go 分布式学习利器(16) -- go中可复用的package构建

    通过本文,你将了解go 语言中如何将自己的package构建到项目中 以及如何将远程(github)的package构建到项目中. 1. 构建本地的package package 是可复用模块的基本单 ...

  2. Go 分布式学习利器(11)-- Go语言通过单链表 实现队列

    一个小实验,将之前学习的Go相关的语法做个总结. 包括: Go语言接口特性 Go语言封装特性 Go语言 变量,指针,函数 语法 GO语言 条件和循环语句 的语法 GO语言的测试程序 通过链表实现一个队 ...

  3. Go: 分布式学习利器(2)-- Go中的变量,常量 以及与其他语言变量之间的差异

    文章目录 1. Go 语言编写测试代码 2. Go 的变量 3. Go 常量定义 1. Go 语言编写测试代码 源码文件以 _test结尾: xxx_test.go 测试方法名需以Test开头: fu ...

  4. Go 分布式学习利器(14)-- Go语言的错误处理

    1. Go 的错误机制 Go 语言的错误机制中与其他语言的主要差异如下: 没有异常机制 error 类型实现了 error接口 type error interface {Error() string ...

  5. Go 分布式学习利器(13)-- Go语言的多态

    文章目录 1. 基本的多态实现 2. 空接口与断言 3. Go接口的最佳实践 1. 基本的多态实现 我们知道C++中实现多态是通过虚函数表 和 继承来 实现的. 类似如下代码: class Progr ...

  6. Go 分布式学习利器(10)-- Go语言的接口

    文章目录 1. 接口与依赖 2. 自定义类型 1. 接口与依赖 在上一节中我们讨论Go语言的面向对象特性的时候也说了,Go语言并不支持继承,能够进行对象的封装(包括数据成员和成员函数的封装),那么这里 ...

  7. Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现

    文章目录 1. Go语言的结构体 -- 数据成员的封装 2. Go (函数成员)行为的定义和实现 1. Go语言的结构体 – 数据成员的封装 Go语言官方给的描述是 既是面向对象语言,也不算面向对象语 ...

  8. Go:分布式学习利器(1) -- 开发环境搭建 + 运行第一个go程序

    文章目录 为什么要学习 go 开发环境搭建 -- MAC 运行第一个go程序 go 函数的返回值设置 go 函数的命令行参数 为什么要学习 go 在如下几个应用场景的需求下产生了go: 超大规模分布式 ...

  9. Go 分布式学习利器(20)-- Go并发编程之多路选择和超时控制,channel的关闭和广播

    Select 多路选择 基本使用语法如下: select {case ret := <-retCh1: //阻塞事件,等待channel1的消息t.Logf("result %s \n ...

最新文章

  1. Java过滤器与SpringMVC拦截器之间的关系与区别
  2. 编程之美-字符串移位问题方法整理
  3. python 锁 多进程
  4. php qq接收不了,php imap接收qq邮件的问题
  5. Jupyter Notebook的安装及问题解决方案
  6. 自然语言10_分类与标注
  7. 模块讲解----XML模块
  8. 云知梦Jquery视频教程 jq重入门到精通 共12集
  9. ams1117 lm317 对比_LM317的使用
  10. android 电视 刷机,康佳电视通用刷机救砖教程分享
  11. 腾讯云游戏多媒体解决方案
  12. Only one connection receive subscriber allowed.
  13. 定时监控Ubuntu系统HDMI热插拔进行锁屏操作
  14. //5. 有若干本图书,图书信息包括图书书名、作者、出版社和价格。要求输出图书价格(const成员函数), //显示图书书名、作者、出版社(非const成员函数)、根据图书书名查找图书并显示相关信息等
  15. js jquery 3D模型展示
  16. LVGL_V8.2 时钟动画 (持续更新中)
  17. java JFreechart开发报表的实例demo下载
  18. 香港的房价到底贵得有多吓人?用数据挖掘告诉你真相
  19. 嵌入式开发难吗?嵌入式多久可以学会?
  20. matlab规定形式化简多项式,如何用matlab化简多项式

热门文章

  1. css3之transition、transform、animation比较
  2. 数据结构学习(十三)、快速排序
  3. 通过代理进行页面传值
  4. groovy–流程控制
  5. Ext结合DWR的关键代码(运行成功的DWRProxy)
  6. python3-pwntools教程_python的pwntools工具的日常使用
  7. linux远程开机windows,从Linux到Windows的PowerShell远程处理
  8. Php中数组sort举例,php数组排序之krsort与asort函数应用举例
  9. Linux找头文件规则,linux 头文件、库文件查找顺序
  10. linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)