熟悉面向对象的小伙伴们可能会知道封装,继承和多态是最主要的特性,为什么前辈们会如此看重这三种特性,真的那么重要吗?

什么是封装

什么是封装,封装有什么好处以及怎么实现封装?

相信大多数小伙伴们都有自己的理解,简而言之,言而简之,封装是屏蔽内部实现细节,仅仅对外暴露出有价值接口.

正如平时工作中使用的电脑一样,我们并不关心电脑的内部组成,只要会开机关机等基本操作就能正常使用电脑,即便坏了的话,也是送去专业维修店进行修理,作为使用者来说,我们从始至终并不关心电脑的工作原理以及它如何工作,唯一在乎的就是怎么能够上网.

之所以我们能如何方便地使用电脑进行网上冲浪,完全得益于电脑设计者对普通用户屏蔽了无关细节,只暴露有价值的操作方法,这种实现方式就是封装.

回到编程语言上,Go 语言作为一种通用的编程语言,和其他主流的编程语言一样支持封装,Go 语言关于封装的实现主要包括两部分:

  • 数据结构的封装
  • 行为方法的控制

其中数据结构的封装主要是使用结构体关键字 struct 实现,而行为方法的控制是用首字母大小写区分是否对外可见.

关于 Go 如何实现封装的细节,可以参考前一篇文章: go 学习笔记之详细说一说封装是怎么回事

继承是怎么回事

说完封装,接着说一下继承是怎么回事?

继承正是在封装的基础上逐步发展产生的概念,我们知道封装是对某一类行为事物模型的抽象,而这种抽象恰恰是由人定义实现的,因人而异也就导致了封装并没有统一的标准答案.

于是乎就可能存在着这么一种情况,对于生活中常见的猫和狗,两个人分别有两种封装方式:

A: 猫是一种宠物,淘气可爱会卖萌,看家本领抓老鼠,偶尔还会喵喵喵.

B: 狗是一种宠物,忠实听话能看家,嗅觉灵敏会破案,一言不合汪汪汪.

C: 我想要买一个宠物,文能卖萌,武可退敌,明个一早给我送来吧!

由于客户C并没有特别说明要的是猫还是狗,A以为是猫,因为猫安静的时候很萌很可爱,生气的时候用小爪爪挠你!

B以为是狗,汪星人的名气可不是自吹自擂,真的要惹怒了它,咬住不放能生生撕下一块肉,你说这种武力值强不强大?

于是第二天,客户C懵逼了,怎么一下子送来了猫狗两个宠物啊,可是又不能食言,因为A和B说的都有道理啊!

等 A和 B走了后,C望着送来的猫和狗,不禁陷入了深思:我只是想要一个宠物而已,非要给我猫和狗两个选择,我有选择困难症啊!

说完这个故事,刚开始会觉得有些滑稽,C只要随便选择一种宠物不就好了吗,干嘛非要全盘接收弄得自己不开心呢?

不知道正在看的读者有没有选择困难症的经历,面对多种选择,一时不知道到底选择哪一个,最终结果可能有三种情况:全盘肯定,全盘否定和部分肯定.

上述故事中,C选择的是全盘肯定,A和B送来的猫和狗都是宠物,没理由拒绝任何一个,于是C选择全盘肯定,当然至于以后是否后悔只有 C自己心里清楚.

前车之鉴可以为师矣,如果下次我们也遇到这种情况应该如何选择呢?

相信聪明的你心中已经有了自己的答案,大声的说出来吧!我就要喵喵喵!

上述案例就好比同事间一起去吃饭,点餐时问你点些什么?你说随便!

原本是好意,以为能自己这么说能方便其他人,其实这种看似不挑剔的做法,对他人来说可能也是最难办的事情.

因为随便的范围太宽泛了,什么都可以也就意味着很大可能上并不会令你满意,你在方便别人的同时,他人也在想法设法取悦于你,不知道你的喜好,心里就犯嘀咕了,这个他喜不喜欢吃呢?

所以,请不要再说随便,勇敢亮出你的观点态度,哪怕不被认可满足.

故事中 A觉得猫是宠物,B觉得狗是宠物,因而当客户真的要宠物时,A和 B都把各自的宠物送上去了,因此问题出现在宠物的定义上,到底什么算是宠物?

其实C心中已经有了宠物的定义,那就是"文能卖萌,武可退敌",而猫和狗恰好都具备这种特性,因此对外宣传时就不要再说这种默认的属性,应该亮出自己的特色!

A: 猫会抓老鼠

B: 狗能认清路

C: 我要一种宠物,出现意外时能帮助到我的话,那就再好不过了!

如果一开始他们就这样说的话,C真正需要的宠物到底是猫还是狗就一目了然了,也不会陷入选择困难症了!

如何实现继承

回到封装的话题上来,转换成编程语言就是A把猫封装成宠物了,B把狗封装成宠物了,而 C需要宠物时,猫和狗都是宠物,最终结果要么是程序依旧正常运行,要么是程序意外挂掉了,因为很可能某一种宠物可能并不符合特定需求.

这种重复定义问题归咎于封装的标准不同,猫和狗两者的封装过程是独立进行的,并没有在一起商量着看看能不能继续抽象出通用模型,混乱的封装导致了猫是宠物,狗也是宠物.

这种多种相关概念的封装很容易出现此类问题,所以适当进行统一分析继续抽象出更高层次的封装概念尤为重要,基于此,原来的封装就能从这种通用概念中解放出来,仅仅保留自己的特色就好,大大简化了模型的语义.

普通封装的概念和更高层次的抽象封装概念的关系就是面向对象中的继承,即猫继承于宠物,表示猫不但拥有宠物的特点还有猫自己的亮点.

对于狗也是一样,狗是宠物,狗也是狗自己本身,体现了自己的特点.

Go 语言和其他主流的面向对象语言有所不同,Go 并不支持继承特性,因而也没有单继承,多继承,重写方法等复杂概念.

Go 是如何描述这种普通封装和抽象封装之间的关系呢?

肯定不是把猫定义成宠物,狗也定义成宠物那种方式!

Go 实现继承的语义不是通过 extends 关键字而是通过结构体组合的方式,请看相关代码.

  • 宠物就应该能文能武,这里不关心结构体的字段,因而并没有定义相关字段.
type Pet struct {
} func (p *Pet) Skill() {
fmt.Println("能文能武的宠物")
}
  • 猫是能够抓老鼠的宠物,Go 采用组合的方式表达继承的语义.
type Cat struct {
p *Pet
} func (c *Cat) Catch() {
fmt.Println("老鼠天敌喵喵喵")
}
  • 狗是自带导航功能的宠物,看我导盲犬的超能力!

type Dog struct {
p *Pet
} func (d *Dog) Navigate() {
fmt.Println("自带导航汪汪汪")
}

接下来,C开始检验猫和狗作为宠物是否具备能文能武的基本要求,与此同时有没有自身的特色?

func TestExtendInstance(t *testing.T) {
p := new(Pet) d := new(Dog)
d.p = p // 自带导航汪汪汪
d.Navigate()
// 能文能武的宠物
d.p.Skill() fmt.Println() c := new(Cat)
c.p = p // 老鼠天敌喵喵喵
c.Catch()
// 能文能武的宠物
c.p.Skill()
}

上述结果证明,Go 语言虽然不支持 extends 关键字表达的继承特性,但是采用组合的方式也是可以实现继承语义的,毕竟,黑猫还是白猫,抓住老鼠的才是好猫!

面向对象的封装和继承暂时告一段落,下一篇文章中将开始讲解接口,以及面向对象中最后的一个概念: 多态!

感谢你的阅读,如果本文对你有所帮助,还望你能留言告诉我,也欢迎分享转发哟!

go 学习笔记之是否支持以及如何实现继承的更多相关文章

  1. springmvc学习笔记(19)-RESTful支持

    springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...

  2. Java学习笔记--脚本语言支持API

    Java语言的动态性之脚本语言支持API 随着Java平台的流行,很多的脚本语言(scripting language)都可以运行在Java虚拟机啊上,其中比较流行的有JavaScript.JRuby ...

  3. Docker学习笔记-Windows系统支持(一)

    Docker对windows的支持情况: 一.Docker for Windows ServerDocker Enterprise Edition for Windows Server 2016htt ...

  4. SpringBoot学习笔记(7)-----CORS支持解决跨域问题

    在实际应用开发中,跨域是一个比较常见的问题,解决方法可以用jsonp,frame,cors等, 这里示例的是SpringBoot对CORS的支持的三种实现方式 第一种:配置一种全局的支持,这种方式需要 ...

  5. CUBRID学习笔记 16 元数据支持

    简化了很多 ,在sqlserver需要用语句实现的功能 接口如下 public DataTable GetDatabases(string[] filters) public DataTable Ge ...

  6. openerp学习笔记 计算字段支持搜索

    示例1: # -*- encoding: utf-8 -*-import poolerimport loggingimport netsvcimport toolslogger = netsvc.Lo ...

  7. entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT

    Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...

  8. JavaScript高级程序设计学习笔记--面向对象的程序设计(二)-- 继承

    相关文章: 面向对象的程序设计(一) — 创建对象 http://www.cnblogs.com/blackwood/archive/2013/04/24/3039523.html 继承 继承是OO语 ...

  9. entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH

    Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...

随机推荐

  1. 如何在一个项目中兼容Wepy和Taro?

    背景交待 NJ 项目启动初期,团队技术栈主要是基于 Vue,技术选择上就选择了类 Vue 的 wepy.迭代几个版本后 mpvue 出来了,简单调研了下,准备基于 mpvue-simple 开发部分页 ...

  2. Excel催化剂开源第14波-VSTO开发之单元格区域转DataTable

    在Excel开发过程中,大部分时候是和Range单元格区域打交道,在VBA开发中,大家都知道的一点是,不能动不动就去遍历所有单元格,那性能是非常糟糕的,很多时候,是需要把整个单元格区域装入数组中再作处 ...

  3. 个人永久性免费-Excel催化剂功能第18波-在Excel上也能玩上词云图

    这年头数据可视化日新月异,在Excel上做数据分析,最后一步,难免要搞个图表输出高大上一回,微软也深知此道,在Excel2016上更新了一大波图表功能,市场上很耀眼的词云图还是没加进来,虽然在各大的在 ...

  4. string的赋值

    string的赋值 string s1="123456"; 一:     只能在刚开始定义的时候用: (1)     从后往前赋值     string s2(s1,3);     ...

  5. CSS画出三角形(利用Border)

    画出三角形的原理是调整border(边框)的四个方向的宽度,线条样式以及颜色. 如果你将宽度调的足够大,改变不同方向的颜色,你就可以发现盒模型的border是四个梯形一样的线条. div{ width ...

  6. .net持续集成sonarqube篇之 sonarqube集成单元测试

    系列目录 通过前面章节我们可以看到,不论怎么构建,单元测试覆盖率一栏总是0% 这是因为单元测试覆盖率报告需要额外集成.这一节我们就讲解如何在sonarqube里集成单元测试覆盖率报告. 这里需要借助O ...

  7. sklearn学习 第一篇:knn分类

    K临近分类是一种监督式的分类方法,首先根据已标记的数据对模型进行训练,然后根据模型对新的数据点进行预测,预测新数据点的标签(label),也就是该数据所属的分类. 一,kNN算法的逻辑 kNN算法的核 ...

  8. 菜单(menu)

    菜单 menu ——菜单默认隐藏 ——实现菜单的接口: Menu,父接口,用于创建主菜单 SubMenu继承Menu接口,用于创建子菜单 ContextMenu接口继承Menu接口,用于创建上下文菜单 ...

  9. Wireshark着色规则

    wireshark抓包蓝色和红色 在默认情况下 蓝色适合红色相反的方向 绿色背景的是HTTP包灰色背景的是TCP包.黑色背景的是TCP错误包或者校验和错误的包 有时候wireshark抓的包还有颜色区 ...

  10. 反应式微服务框架Flower

    Flower是一个构建在Akka上的反应式微服务框架,开发者只需要针对每一个细粒度的业务功能开发一个Service服务,并将这些Service按照业务流程进行可视化编排,即可得到一个反应式系统. 即时 ...