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

什么是封装

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

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

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

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

回到编程语言上,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. http://www.jianshu.com/p/2dd54ec0bb43 程序员纪录片

    http://www.jianshu.com/p/2dd54ec0bb43 程序员纪录片

  2. [机器学习] k-近邻算法(knn)

    最近在参加大数据的暑期培训,记录一下学习的东西. 引言 懒惰学习法:简单的存储数据,并且一直等待,直到给定一个检验数据,才进行范化,以便根据与存储的训练元组的相似性对该检验数据进行分类.懒惰学习法在 ...

  3. 转载——Asp.Net MVC+EF+三层架构的完整搭建过程

    转载http://www.cnblogs.com/zzqvq/p/5816091.html Asp.Net MVC+EF+三层架构的完整搭建过程 架构图: 使用的数据库: 一张公司的员工信息表,测试数 ...

  4. Java中使用 foreach 操作数组

    foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英文字面意思理解 foreach 也就是" for 每一个& ...

  5. Python基础之格式化输出、运算符、数字与布尔值互换以及while...else

    python是一天学一点,就这样零零碎碎…… 格式化输出 %是占位符,%s是字符串格式,%d整数格式,%f是浮点数格式 name = input('输入姓名') age = input('输入年龄') ...

  6. python的乘法口诀表

    python的乘法口诀表 python的乘法口诀表 用python来写一个脚本,使得这个脚本在运行后自动输出乘法口诀表. pyton的脚本如下: #!/usr/bin/env python #codi ...

  7. web-inf与meta-inf

    /WEB-INF/web.xml Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则. /WEB-INF/classes/包含了站点所有用的 class 文件,包括 ser ...

  8. Drools规则引擎-如果判断某个对象中的集合是否包含指定的值

    规则引擎集合相关处理 在实际生产过程中,有很多关于集合的处理场景,比如一个Fact对象中包含有一个集合,而需要判断该集合是否包含某个值.而Drools规则引擎也提供了多种处理方式,比如通过from.c ...

  9. scroll-苹果滑动卡顿

    2018年08月02日,程序小bug. 在移动端html中经常出现横向/纵向滚动的效果,但是在iPhone中滚动速度很慢,感觉不流畅,有种卡卡的感觉,但是在安卓设备上没有这种感觉; 一行代码搞定: - ...

  10. 关于定时器Scheduled(cron)的问题

    定时器配置步骤参考:http://blog.csdn.NET/sd4000784/article/details/7745947 下面给出cron参数中各个参数的含义: CRON表达式    含义 & ...