封装

所谓封装,就是将属性和方法捆绑到一起,封装到一个对象中去,简单的说,你是人,你有许多属性,比如说你的姓名,年龄,身高,体重,性别,性格,爱好等等,这是属性;而同时,你又会吃饭,睡觉,工作,学习,做事情,这些是方法,是你所具有的;同时将属性和方法封装到一个类中去,就能很完美的描述这个类的特征了,同时,它所具有的方法也就一起集成到类中,方便使用。这些是简单的描述了。
至于什么时候需要这个似乎不是讨论的重点了,既然是java号称完全面向对象的语言,那么,你就应该一直以封装方式去思考问题和设计类了。

 
 
隐藏复杂性,是我们人类处理更复杂问题的一种常用方法。这可能跟人的记忆力、计算力等是有限的这点有关,对这种方法背后原因的深度挖掘,要涉及人类认知学方面的知识,而显然它(认知学)的表现并不尽如人意,否则完全可以根据它造出会认知的机器来。

这里不讨论认知学与强人工智能,感兴趣的读者可以找些这方面的资料来读。我们只要知道,这种隐藏复杂性的方法很常用、很好用就可以了,比如操作电视,我们不需要知道电视内部的繁杂的布线,只通过几个电视按钮就可以实现调整音量、切换频道等等功能;软件中,面向对象中的封装,就是对这一基本方法的体现。

 
  对象的封装,要分两个方面来考察,一个是怎么样封装才算对,一个是怎么样封装才算好。

    达到了封装者对对象的职责预期就是对的,否则,就是错的。

 
 
 比如,想得到的是一个狗对象,能狗叫,而封装的结果竟然是个猫,会猫叫。又比如,想得到的是一个狗对象,能狗叫,而封装的结果是一个狗对象,却能猫叫。这都是没有达到封装预期所致。但也有这种情况,有人先封装了一个对象后,接着说,这个对象就是我的预期,这样做就像打哪儿指哪儿的神枪手一样,预期永远与封装的对象相符合,那么我们只能考察它的另一项指标:好不好。

而评价封装的好不好,很难有一个客观的标准,不管从哪个角度说,,它都更属于设计美学范畴。当一种封装显得不怎么美的时候,就是不太好。怎么又算美呢?这真的很难说;一千个人可能会有一千种关于美的评价吧。我只能说一下我自己的审美倾向,简洁既是美。

简洁的追求会自然促使你让类的职责单一,比如一个狗对象,不但会狗叫,也能猫叫,那么猫叫就是很不和谐的音符,这就显得不美。狗对象只表现狗的行为则显得更为合适,表现的太多,反而会感觉很怪异。假如来了只猫对象,见到这只会猫叫的狗,一定感觉很不是滋味。程序是给程序员看的,职责明确而接口简单的对象,看起来会更舒服,可读性也一定会更好。职责模糊而接口复杂的对象,看起来总不那么舒服(虽然也能实现所有业务功能)。

我们还是看一段具体的程序吧。这是一个计数器程序。

这个类只有一个属性,对应到这个对象,则这个类属性代表着对象的状态,所有的方法,都是围绕着对象的基本属性或状态进行的操作,没有和基本属性无关的操作。这个对象的职责就是负责计数。很简洁。假如我们再添加一个方法,如下:

public
int max(int a,int b){

if(a>b) return
a;

else return
b;

}

  那么这个方法对于这个计数器对象来说,就是相当于狗对象中有了猫叫,就是不和谐的,就是不美的。这个方法和计数器的职责是无关的,它也没有涉及到类属性的任何操作,如果一个操作对它自身没有任何影响,这好像更应该是别的对象的方法。所以,把取得最大值这种方法放在这里是很累赘的。

  既然是在进行封装和信息隐藏,就要区别于开放和信息暴露,那么在能完成特定职责的情况下,封的越严实越好,信息隐藏的越多越好,留的接口越少越好,这样的对象的功能才强大而接口又简洁。这种简洁的美感怎么表述呢,我总认为苹果公司的各种产品的界面设计最能体现出这种简洁美感。IPod的界面和操作设计,就有一种艺术般的简洁美感。而面向对象设计中的封装,也应该向iPod的封装效果学习。

  比如两个同类型对象,如果它们的id属性相等,则认为这两个对象相等。有两种办法判断相等,一种是分别通过两个对象提供的接口取出对象id,再在对象外的程序中做id的比较逻辑判断(例如:if
a.id=b.id then…);一种是对象本身提供是否相等的方法,在对象内部完成此判断,外人看不到(例如:if a.equal(b)
then…)。这样,把实现细节隐藏在内部,显然这样的封装的更加合理,使用起来也更加的方便。这就像操作轿车,如果轿车的接口是这样:按一个按钮,弹出一根线,再按下另一个按钮,弹出另一根线,然后司机用手把两根线一碰,汽车发动了!虽然也能发动汽车,但未免太麻烦了;这种发动汽车的方式就像比较两个对象是否相等的例子中的前者,这样做肯定也是能发动着汽车的,就像很多封装的不好的对象一样能实现要求的功能一样(比如比较对象是否相等的第一个例子)。一拧钥匙,汽车就发动,明显优于手工碰线头的方式。

一想起封装与信息隐藏,我总是会不由自主的想起《自私的基因》一书的作者道金斯说的关于基因的一段话:

  在今日,别以为它们(基因)还会浮游于海洋之中了。很久以前,它们已经放弃了这种自由自在的生活方式了。在今天,它们群集相处,安稳地寄居在庞大的步履蹒跚的“机器”人体内,与外界隔开来,通过迂回曲折的间接途径与外部世界联系,并通过遥控操纵外部世界。它们存在于你和我的躯体内;它们创造了我们,创造了我们的肉体和心灵;而保存它们正是我们存在的终极理由。这些复制基因源远流长。今天,我们称它们为基因,而我们就是它们的生存机器

时间: 2024-09-29 18:04:55

封装的相关文章

python学习 面向对象封装

from collectoins import namedtuplePoint=namedtuple('point',['x','y'])t1=Point(1,2)print(t1.x)print(t1.y)没有方法的类属性不会发生变化    定义简单 不能改变面向对象封装私有属性!!!私有方法!!!用装饰器描述的几个方法@property !!!@classmethod!!@staticmethod! 封装:class Teacher:     def __init__(self,name,p

python—面向对象的封装

封装 私有属性 class Teacher: __identifier = 'Teacher' #私有静态属性 def __init__(self,name,pwd) self.name = name self.__pwd = pwd #私有属性 内部使用,外部不能使用 def pwd(self): print(self.__pwd) alex = Teacher('alex','3714') alex.pwd() class Teacher: __identifier = 'Teacher'

dbutils封装对象,单列,一行一列(用)

基本用法:查找并封装对象与对象集合 public User findUserByNamePassword(String name,String password){ QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource()); String sql = "select * from user where name='"+name+"' and password = '"+password

python基础--接口与归一化设计、封装、异常、网络编程

1 接口与归一化设计 1.1 归一化概念: 归一化的好处: 1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度. 2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合 继承的两种用途 一:继承基类的方法,并且做出自己改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的.因为它使得子类与基类出现强耦合. 二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中

自动化测试框架 selenium api的封装

接上一篇 http://tianxietaotao.blog.51cto.com/12002420/1951701 这篇我大概介绍下我这个工具的简单介绍 先上图: 制作背景: Web自动化测试在现在测试领域已经越来越普遍,但是写代码对于好多测试猿代码基础较弱,搭建系统也比较麻烦.所以我抽闲暇时间做了这个简单的工具:下面简单介绍下功能 工具简单介绍: 1.工具栏:Resume:调试阶段执行到下一个断点 next:单步执行 debug/run 模式切换 执行.停止 2.用例树:用例采用execl或者

lambda表达式封装对数据库的查询

前言: 1.为什么要封装lambda表达式数据库查询,原因有一下几点: 1.1.在以往的开发中进行数据库表查询时,其实所需要的字段就是其中几个,但是在开发中,开发者往往习惯select * 进行查询,当数据多和用户量多时,查询的效率会降低. 1.2.在写查询where条件的时候,总是用string.format去拼接字符串,开发效率低. 1.3.代码不够优雅,代码中嵌套和多sql语句,如果是表字段发生改变时编译器检查不出来,代码出错的概率大. 1.4.本着 write less  do more

Android封装TitleBar基本适用所有常规开发

Android封装TitleBar基本适用所有常规开发 github地址:https://github.com/SiberiaDante/SiberiaDanteLib/blob/master/sample/src/main/notes/TitleBar.md 主要实现:(后续会继续完善,喜欢的给个star,感谢支持) 使用方法 allprojects { repositories { ... aven { url 'https://jitpack.io' } } } dependencies

将数据库从服务器移到浏览器--indexedDB基本操作封装

数据库是属于服务器的,这是天经地义的事,但是有时候数据也许并非需要存储在服务器,但是这些数据也是一条一条的记录,怎么办?今天来带领你领略一下H5的一个新特性--indexedDB的风骚.你会情不自禁的发出感叹--不可思议! 一.链接数据库 indexedDB没有创建数据库的概念,你可以直接链接数据库,如果你链接的数据库并不存在,那么会自动的创建一个数据库.看下面的这个例子. <!DOCTYPE html> <html lang="en"> <head>

Java基础——封装

最近学习Java面向对象方面的知识点,一直没时间更新博客,因为这块的知识点真的蛮绕的.一个知识点一个知识点的往外冒,而且对于我这个初学者来说区分构造器和方法就花费了一整天的时间.现在准备再重新过一遍知识点. 先背下来一个理念: 面向对象程序设计是将数据放在第一位的,然后再考虑操作数据的方法. 之前,再学习Java的优越性的时候,我们知道了Java是一种面向对象设计的程序设计语言.那到底什么是面向对象程序设计呢?要弄懂它,首先我们简单了解一下另一种程序设计. 一.面向过程程序设计: 面向过程程序设

转 常见视频编码方式以及封装格式

常见视频编码方式以及封装格式 常见视频编码方式 所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式.视频流传输中最为重要的编解码标准有国际电联的H.261.H.263.H.264.H.265,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo.微软公司的WMV以及Apple公司的QuickTime等. AVI AVI 是 Audio Video I