用对象看JAVA

用对象看JAVA

如果我们说另外一种不同的语言,我们会发觉一个不同的世界! — Ludwig Wittgenstein (1889-1951)

很多时候我们在开始学习一门编程语言的时候都过于“急切”,或者说不知道为什么要学习它?而这个问题就像你所选择的专业一样,适合的专业成为你职场拼杀的利器与活命的本钱,不合适则要么选择痛苦承受,要么转战他区。在这里赠言一句,希望能引起大家的思考,走出合适的道路。

OOP 和 Java 不一定适合每个人。请充分考虑后再决定是不是选择 Java。如果你依然选择 Java 作为你的开发语言,我希望你至少应该清楚你选择的是什么,以及为什么选择这个方向。 -----《On Java 8》

对象的概念

语言的灵感来自其他形式的表达,如写作,绘画,雕塑,动画和电影制作。它起源于生活,应用于生活,也反馈给生活。编程语言是创建应用程序的思想结构,而面向对象编程(Object-Oriented Programming OOP)就是一种编程思想方式和编码结构。所以在JAVA这门语言的世界里,对象就是它的灵魂。

抽象

学习过很多的编程语言,相信你对编程语言有了一个比较直观的感触:从最初的汇编语言到(Fortran/basic大概很多人都没有学过)C再到C++/JAVA/Python等编程语言,对于其计算机内部的关注或者学习门槛变得越来越低,而这就是现在许多的主流的编程语言都是面向对象编程的。相对于汇编来说,C语言就是对汇编的一中抽象,但是它们依然考虑计算机的结构,而非问题本身,在C语言之后便是C++,它继承了C语言的很多编程规则,然后在其基础上加入了我们所说的OOP,从计算机本身的结构(数据结构)转向问题本身的结构,到了JAVA/Python这类着重于面向对象编程的语言来说,更加专注于问题,而非计算机了,所以在初学者来说,对于计算机结构、组成、汇编指令等等就被抽象了,抽象成什么呢?就是咱们所学的各种JAVA代码与其相应的机制了。因此,对于抽象来说,所有编程语言都提供了抽象机制。在JAVA这类面向对象编程的语言来说,某种程度上问题的复杂程度取决于对问题中的事物抽象的类型与质量。

那么为什么选择使用抽象去获取对象,从而处理问题呢?相比以前的实现,面向对象编程又有什么进步呢?

在没有面向对象编程的时候,程序员很多时候都是面向过程(函数)编程,程序员必须在机器模型(解决问题的空间)和实际解决的问题模型之间建立起一种关联,从而实现对问题的解决。而这个过程是是否耗费精力,并且偏离了编程语言本身范围的,所以这对于一个初级程序员而言,其代码将变得十分难写,当代码量太多时候,其维护成本变得极其高昂。
而面向对象的程序设计在此基础上,走出了一大步。降低了学习成本,同时这种编程表达也十分具有普遍性,不受限于特定类型的问题。所以我们就将问题空间中的元素与它们在解决空间中的表示称为“对象”Object。所以OOP允许了我们根据问题来描述问题,而不是根据运行解决方案的计算机(运行平台)。所以一定程度上可将每个对象看成一个小的计算机:它们有自己的状态并且可以进行特定的操作。而这与现实中的“物体”很相似,它们都具有各自的特征与行为。

总结下来,JAVA编程语言具有如下五大基本特征:

  1. 万物皆对象。你可以将对象想象成一种特殊的变量。它存储数据,但可以在你对其“发出请求”时执行本身的操作。理论上讲,你总是可以从要解决的问题身上抽象出概念性的组件,然后在程序中将其表示为一个对象。
  2. 程序是一组对象,通过消息传递来告诉彼此该做什么。要请求调用一个对象的方法,你需要向该对象发送消息。
  3. 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。
  4. 每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class)是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。
  5. 同一类所有对象都能接收相同的消息。这实际是别有含义的一种说法,大家不久便能理解。由于类型为“圆”(Circle)的一个对象也属于类型为“形状”(Shape)的一个对象,所以一个圆完全能接收发送给"形状”的消息。这意味着可让程序代码统一指挥“形状”,令其自动控制所有符合“形状”描述的对象,其中自然包括“圆”。这一特性称为对象的“可替换性”,是OOP最重要的概念之一。

一个对象具有自己的状态,行为和标识。这意味着对象有自己的内部数据(提供状态)、方法(产生行为),并彼此区分(每个对象在内存中都有唯一的地址。) ------Grady Booch

接口

在公元前330年左右,提出了哲学史上的“类型”一说,他曾提出了“鱼类和鸟类”这里的类型概念。而这中思想被运用到了面向对象编程中,也就是我们学习JAVA时候使用的class,在第一个面向对象编程语言Simula_67中,它使用了关键字class来引入新的类型(其实Type和Class可以互换,只是Type强调接口,而Class强调那个接口的一种特殊实现类型)。

那么类与对象有什么关系呢?
这里给出一个比较熟悉的例子(银行出纳员):
在这个例子里,我们有一系列出纳员、客户、帐号、交易和货币单位等许多"对象”。每类成员(元素)都具有一些通用的特征:每个帐号都有一定的余额;每名出纳都能接收客户的存款;等等。与此同时,每个成员都有自己的状态;每个帐号都有不同的余额;每名出纳都有一个名字。所以在计算机程序中,能用独一无二的实体分别表示出纳员、客户、帐号以及交易。而这些实体便是“对象”,而且每个对象都隶属一个特定的“类”,那个类具有自己的通用特征与行为。所以类与对象的关系是类包含对象。一个类中可以有许多的对象,反之不行。

现在又回到了最初采用面向对象编程的根源上,那么OOP是如何解决在“问题空间”(问题实际存在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对一”的映射关系呢?换句话说就是如何利用对象完成真正意义上的工作呢?所以我们必须具有一种办法能向对象发出请求,令其解决一些实际的问题,比如一些交易,或者一些操作等等。而且是每个对象只能接受特定的请求。而在OOP中我们称这个请求为“接口(Interface)”。所以“Class”与“Interface”的对应关系就是面向对象程序设计的基础,也就是上面所述的映射关系。

例子总是最好的老师,我们来看看这个简单的例子(灯泡对象):

在这里插入图片描述

Light lt = new Light();
lt.on();

在这个例子中,类(类型)的名称是Light,可向Light对象发出on打开off关闭brighten变亮dim变暗请求。通过声明一个引用,如ltnew关键字,我们创建了一个Light类型的对象,再用等号将其赋给引用。为了向对象发送消息,我们使用句点符号 .lt和消息名称on连接起来。

服务提供

在开发或理解程序设计时,我们可以将对象看成是“服务提供者”。你的程序本身将为用户提供服务,并且它能通过调用其他对象提供的服务来实现这一点。我们的最终目标是开发或调用工具库中已有的一些对象,提供理想的服务来解决问题。

那么问题来了:我们该选择哪个对象来解决问题呢?例如,你正在开发一个记事本程序。你可能会想到在屏幕输入默认的记事本对象,一个用于检测不同类型打印机并执行打印的对象。这些对象中的某些已经有了。那对于还没有的对象,我们该设计成啥样呢?这些对象需要提供哪些服务,以及还需要调用其他哪些对象?

我们可以将这些问题一一分解,抽象成一组服务。软件设计的基本原则是高内聚:每个组件的内部作用明确,功能紧密相关。然而经常有人将太多功能塞进一个对象中。例如:在支票打印模块中,你需要设计一个可以同时读取文本格式又能正确识别不同打印机型号的对象。正确的做法是提供三个或更多对象:一个对象检查所有排版布局的目录;一个或一组可以识别不同打印机型号的对象展示通用的打印界面;第三个对象组合上述两个服务来完成任务。这样,每个对象都提供了一组紧密的服务。在良好的面向对象设计中,每个对象功能单一且高效。这样的程序设计可以提高我们代码的复用性,同时也方便别人阅读和理解我们的代码。只有让人知道你提供什么服务,别人才能更好地将其应用到其他模块或程序中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值