请选择 进入手机版 | 继续访问电脑版
尚学堂集团旗下品牌:尚学堂速学堂百战程序员云数学院[切换校区]
曾经初次接触编程的我来说,一直有一个疑惑,什么是对象?什么又是面向对象?

这个问题即使对一个开发多年的老师傅来说,如果没有深入了解,可能也会懊恼。

如果你是刚接触编程,问老师什么是对象?那么他可能跟你说,万物皆对象。

这个答案其实已经被滥用了,就像“苹果”,“汽车”,这都属于老师口中的对象。

对象作为面向对象编程的核心,我们将对象定义为“包含了属性,过程和数据的集合体,它们可以执行计算并且保存局部的状态。但是这一切都是有一个标准,即对象应具有某种“完整性”,这种完整性不应该被违反,对象只能按照适合它的的方式来改变状态,改变行为,实现操作和其他对象发送关系。

这个“完整性”即对象本身存在的一些不变的特征,就如,电梯就应该在一个有限的空间中直上直下,所有对电梯的模拟都应该包含这个不变的特性,因为它们与电梯的概念是不可分割的整体。

我曾读过这样一句话:计算机科学的本质其实是对图灵机的抽象,一个输出,一个输入,加上计算规则和内部状态。那一刹那,茅塞顿开。

其实对象和函数也是一样,输入即是对外开放的接口(形参),输出指想要返回的数据(返回值),计算规则指对象内部数据的处理,内部状态指对象针对不同事件所做出的反应。

说了这么多,不知道是否让大家对“对象”有更深层次的认识,如果有帮助,不甚感激。

--------------------------------------------------------------------------------------

谈完对象,那就接下来说说什么是面向对象吧?

面向对象不仅是一种思想,也是一种优秀的软件开发方法,它适用于许多行业。在面向对象的思想中,对象模型是基本的构建块,每个对象都属于某个类,而类与类之间的层次结构需具备“是一种”联系,即继承。

为什么面向对象一定要求类与类之间需具备继承关系,这是因为,如果没有继承关系,每个类都会是独立的一个单元,相互之间没有联系,这不符合现实世界中事物的本质,玫瑰是花,牡丹是花,如果没有继承,那么每创造一种花都需要从头设计。

面向对象编程中,重点在于类与类之间的层次结构,以及对象之间的各种交互行为,而这一切的前提,却是利用面向对象最核心的本质——抽象

抽象是我们解决复杂问题的基本方式,通过抽象可以清晰地定义问题边界,观察者只关注自己所需要的特征,这一切都与观察者的视角有关。

不同的抽象层次,可以合理划分系统的层次结构,以及对象的交互方式。准确的抽象,分解出我们需要的,才是我们程序员在开发中所面对的问题。

------------------------------------------------------------------

最后说说面向对象的弊端吧。

面向对象最大的弊端,就是被当成一个套路,广泛使用,以为写几个class,new几个对象,就是面向对象,那就大错特错了。

面向对象不是单单class,而是对实现过程的抽象,通过对这些抽象的封装,对外提供简单的调用方法。

我们不能因为学习的是Java,就以为,因为Java是面向对象的编程语言,所以程序应该是面向对象的,这个观点极其错误。强行使用面向对象来进行编程,这只是一种耍酷。

有些人常回答什么是面向对象这个问题时,只有六个字:封装,继承,多态。但这恰恰在错误的道路上越走越远,就如上面提到的什么是对象,如果一个对象不具备某种完整性,那么不应该作为一个对象。

面向对象真正的特征应该是“封装”“归一化”。

真正的封装是什么?

不是写个class就是封装,更不是写一个函数就是封装。

封装不是对外隐藏,而是对外透明。外部调用者可以顺利得到自己想到的任何功能,而不会看到内部细节的存在。如果只是对外隐藏,那么外部调用者可能会被碍手碍脚的private声明弄得火冒三丈,最终只能通过稀奇古怪的机制,才能访问它需要的功能。

真正的封装,应该是经过深入的思考,做出良好的抽象,给出最小的接口,并使得可以对外透明。

最后再强调一下,别生硬地放进private里面东西,否则以后需要这个东西时候,你不得不写一个get方法,这种类似“访问函数”的渣渣,在封装上挖洞洞的行为,让人看得恶心。

什么是归一化?

说到归一化,需要先说说继承真正的含义。

继承具备两种含义,第一个是继承基类的方法,并作出改变和扩展,解决代码重用问题。
第二个是声明某个子类兼容某基类,外部调用者无需关心差别。

继承的第一个含义意义不大,它使子类和基类强度耦合。而继承的第二种含义才是关键,它又叫“接口继承”。

接口继承实质上是要求做出一个良好的抽象,规定一个兼容接口,使得外部调用者无需关心具体细节,可以一视同仁处理实现特定接口的所有对象,这在程序设计上,叫做“归一化”。

归一化使得我们不可以不需要区分的处理所有接口兼容的对象集合,就比如在java中一切对象都可以使用toString方法,jdbc连接等。

归一化可以很大程度上简化使用者的处理逻辑。通过封装和归一化,我们可以灵活地应对需求变更。

至于多态,其实只是一种依附于继承的两种含义。基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。

没有多态,继承的含义将不能实现。将继承和多态,封装并列这显然是不符合逻辑的,不假思索的就把它们当成并列概念使用的人,显然是被误导了。


最后总结下,封装应付需求变更,归一化可以简化设计,这是面向对象最基本的好处,也是我们学习面向对象本该理解的思想。合理地划分层次,去除不必要的信息,一层层向上提供简洁并完备的信息和接口,才是面向对象编程最难也是最优的设计方法。

最后的最后,不是使用面向对象语言写出来的程序就是面向对象,不是写几个class就是面向对象,我们真正应该学习的是面向对象的思想,而不是使用它附带的东西。

写下这篇文章是对过去知识的总结,也是一次对未来的展望。希望看到这篇文章的人可以加深理解,写出更好的程序。


分享到 :
人收藏 回复 使用道具
*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部