Java——对象与类

1.面向对象程序设计概述

①面向对象程序设计(简称OOP)是当今主流的程序设计范型,它已经取代了20世纪70年代的“结构化”过程化程序设计开发技术。而Java是完全面向对象的,必须熟悉OOP才能够更好的编写Java程序。 

②面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。究竟是自己构造对象,还是从外界购买对象完全取决于开发项目的预算和时间。但是,从根本上说,只要对象能够满足要求,就不必关心其功能的具体实现过程。在OOP中,我们不比关心对象的具体实现,只要能够满足用户的需求即可。

③对于一些规模较小的问题,将其分解为过程的开发方式比较理想。而面向对象更加适用于解决规模较大的问题。要想实现一个简单的Web浏览器可能需要大约2000个过程,这些过程可能需要对一组全局数据进行操作。采用面向对象的设计风格,可能只需要大约100个类,每个类平均包含20个方法。当然后者是更易于程序员掌握的,也容易在其中找到bug。假设给定对象的数据出错了,在访问这个数据项的20个方法中查找错误要比在2000个过程中查找容易得多。

2.类 

类(class)是构造对象的模板或蓝图。我们可以将类想象成制作小甜饼的切割机,将对象想象为小甜饼。由类构造(construt)对象的过程称为创建类的实例(instance)。

正如博主之前发布的使用Java语言AC的ZZULIOJ上前120道题,用Java编写的所有代码都位于某个类的内部。标准的Java库提供了几千个类,可以用于用户界面设计、日期、日历和网络程序设计。尽管如此,还是需要在Java程序设计中创建一些自己的类,以便描述应用程序所对应的问题域中的对象。

封装(encapsulation,有时称为数据隐藏)是与对象有关的一个重要概念。从形式上看,封装不过是将数据和i行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域(instance field),操纵数据的过程称为方法(method)。对于每个特定的类实例(对象)都有一组特定的实例域值。这些值的集合就是这个对象的当前状态(state)。无论何时,只要向对象发送一个消息,它的状态就有可能发生改变。

实现封装的关键在于绝对不能让类中的方法直接的访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。封装给对象赋予了“黑盒”特征,这是提高重用性和可靠性的关键。这意味着一个类可以全面的改变存储数据的方式。只要依旧使用同样的方法操作数据,其他对象就不会知道或介意所发生的变化。

那么,OOP的另一个原则会让用户自定义Java类变得轻而易举,这就是:可以通过扩展一个类来建立另外一个新的类。事实上,在Java中,所有的类都源自于一个“神通广大的超类”,它就是Object,我们会在后面的陆续介绍。

在扩展一个已有的类时,这个扩展后的信类具有所扩展的类的全部属性和方法。在新类中,只需提供适用于这个新类的新方法和数据域就可以了。通过扩展一个类来建立另外一个类的过程称为继承(inheritance)。

3.对象 

要想使用OOP,一定要清楚对象的三个主要特性:

①对象的行为(behavior)——可以对对象施加哪些操作,或可以对对象施加哪些方法?

②对象的状态(state)——当施加那些方法时,对象如何响应?

③对象标识(identity)——如何辨别具有相同行为与状态的不同对象?

同一个类中的所有对象实例,由于支持相同的行为而具有家族式的相似性。对象的行为是用可调用的方法定义的。

此外,每个对象都保存着描述当前特征的信息,这就是对象的状态。对象的状态可能会随着时间而发生改变,但这种改变不是自发的。对象状态的改变必须是通过调用方法实现的(如果不经过方法的调用就可以改变对象的状态,只能说明封装性遭到了破坏)。

对象的这些关键特性在彼此之间相互影响着。例如,对象的状态影响它的行为(如果一个订单“已送货”或“已付款”,就应该拒绝调用具有增删订单中条目的方法。反过来,如果订单是“空的”,即还没有加入预定的物品,这个订单就不应该进入“已送货”状态)。

4.识别类

在传统的过程化程序设计中,必须从顶部的main函数开始编写程序。那么在面向对象程序设计时,就没有所谓的“顶部”,而是从设计类开始,然后再往每个类中添加方法。

识别类的简单规则则是在分析问题的过程中寻找名词,而方法对应着动词。

例如,在订单处理系统中,有这样一些名词:

项目(Item)、订单(Order)、送货地址(Shipping address)、付款(Payment)、账户(Account),这些名词很可能称为类Item、Order等。

接下来,查看动词:物品项目被添加到订单中,订单被发送或取消,订单货款被支付。对于每一个动词,例如:“添加”、“发送”、“取消”以及“支付”,都要标识出主要负责完成相应动作的对象。例如:当一个新的条目添加到订单中时,那个订单对象就是被指定的对象,因为它知道如何存储条目以及如何对条目进行排序。也就是说添加(add)就应该是Order类的一个方法,而Item对象是一个参数。

当然,所谓“找名词与动词”来区别类和方法,在原则上只是一种经验。在创建类的时候,哪些名词是类、哪些动词是方法,更重要的完全取决于个人的开发经验。 

5.类之间的关系 

在类之间,最常见的关系有三种:①依赖(“uses-a”),②聚合(“has-a”),③继承(“is-a”)

①依赖(dependence):即“uses-a”关系,是一种最明显、最常见的关系。例如:Order类使用Account类是因为Order对象需要访问Account对象查看信用状态,我们就说Order类依赖于Account类。但是Item类不依赖于Account类,这是因为Item对象与客户账户(Account)无关。因此,如果一个类的方法操纵另一个类的对象,我们就说一个类依赖于另一个类。当然了,我们应该尽可能的将相互依赖的类减至最少。如果类A不知道类B的存在,它就不会关心类B的任何改变(这就意味着B的改变不会导致A产生任何bug),用软件工程的术语来说,就是让类之间的耦合度最小。

②聚合(aggregation):即“has-a”关系,是一种具体且易于理解的关系。例如:一个Order类的对象包含一些Item类的对象。聚合关系意味着类A的对象包含类B的对象。

③继承(inheritance):即“is-a”关系,是一种用于表示特殊与一般关系的。例如:RushOrder类由Order类继承而来,在具有特殊性的RushOrder类中包含了一些用于优先处理的特殊方法,以及一个计算运费的不同方法;而其它方法,如:添加条目、生成账单等都是从Order类继承来的。一般而言,如果类A继承类B,类A不但包含从类B继承的方法,还会拥有一些额外的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章