第二章 理解面向对象
Java语言是纯粹的面向对象的程序设计语言,这主要表现为Java完全支持面向对象的三种基本特征:继承、封装、多态。Java完全支持使用对象、类、继承、封装、消息等基本概念来进行程序设计。
面向对象的方式实际上由OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)三个部分有机组成,其中OOA和OOD的结构需要使用一种方式来记录描述,目前业界统一采用UML(统一建模语言)来描述并记录OOA和OOD的结果。常用的UML图形有用例图、类图、组件图、部署图、顺序图、活动图和状态机图。
在目前的软件开发领域有两种主流的开发方法:结构化开发方法和面向对象开发方法。
结构化程序设计简介:
结构化程序设计方法主张按功能来分析系统需求,其主要原则可概括为自顶向下、逐步求精、模块化等。结构化程序设计首先采用结构化分析(Structured Analysis SA)方法对系统进行需求分析,然后使用结构化设计(Structured Designed SD)方法对系统进行概要设计、详细设计,最后采用结构化编程(Structured Program SP)方法来实现系统。因为结构化程序设计方法主张按功能将系统逐步细分,因此这种方法也称为面向功能的程序设计方法。结构化程序设计里最小的程序单元是函数,每个函数都负责完成一个功能,用以接收一些输入数据,函数对这些输入数据进行处理,处理结束后输出一些数据。整个软件系统由一个个函数组成,其中作为程序入口的函数称为主函数,主函数依次调用其他普通函数,普通函数之间依次调用,从而完成整个软件系统的功能。
程序的三种基本结构:
算法的实现过程是由一系列操作组成的,这些操作之间的执行顺序就是程序的控制结构。任何简单或复杂的算法,都可以由顺序结构、选择结构、循环结构这三种接本结构组合而成。
顺序结构:只有一个入口点a和一个出口点b,特点是程序从入口点a开始,按顺序执行所有操作,直到出口点b。
选择结构:表示程序的处理需要根据某个特定的条件选择其中的一个分支执行。选择结构有单选择、双选择、多选择三种。
循环结构:程序反复执行某个或某些操作,直到某个条件为真(或为假)时才停止循环。分为当型循环和直到型循环两种。
当型循环:先判断条件,为真时执行循环体,为假则退出循环体。即先判断后执行。
直到型循环:直接执行循环体,结束时判断条件,为真继续循环,为假退出循环。即先执行后判断。
虽然Java是面向对象的,但Java的方法里则是一种结构化的程序流。
面向对象程序设计简介:
强调以对象为中心来思考,并根据对象的本质特点,把他们抽象的表示成系统中的类,作为系统的基本构成单元。
成员变量(Field 状态数据)+ 方法(method 行为) = 类定义
面向对象方法具有三个基本特征:封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism),其中封装指的是将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能;继承是面向对象实现软件复用的重要手段,当子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法;多态指的是子类对象可以直接赋给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时可能表现出多种行为特征。
除此之外,抽象也是面向对象的重要部分,抽象就是忽略一个主题之中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。(虽然抽象是面向对象的主要部分,但它不是面向对象的特征之一,因为所有的编程语言都需要抽象)
对象之间的相互协作需要一个机制协助进行,这样的机制称为“消息”,消息是一个实例与另一个实例相互通信的机制。
继承具有传递性,Java中仅支持单继承。
在编程语言领域,还有一个“基于对象”的概念,这两个概念极易混淆。通常而言,“基于对象”也使用了对象,但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说“基于对象”没有继承的特点;而“多态”则更需要继承,没有了继承的概念也就无从谈论“多态”。面向对象方法的三大基本特征缺一不可。例如,JavaScript语言就是基于对象的,他使用一些封装好的类,调用对象的方法,设置对象的属性,但是他们无法让开发者派生新的类,开发者只能使用现有对象的属性和方法。
UML(统一建模语言)介绍:
面向对象软件开发需要经过OOA、OOD、OOP三个阶段。OOA对目标系统进行分析,建立分析模型,并将之文档化;OOD用面向对象的思想对OOA的结果进行细化,得出设计模型。OOA和OOD的分析、设计结果需要统一的符号来描述、交流并记录,UML就是这种用于描述、记录OOA和OOD结果的符号表示法。
UML图大致可分为静态图和动态图两种
从上图可以看出,UML一共包括13种正式图形:用例图(use case diagram)、类图(class diagram)、包图(package diagram)、组件图(component diagram)、对象图(object diagram)、部署图(deployment diagram)、复合结构图(composite structure diagram)、顺序图(sequence diagram)、通信图(communication diagram)、状态机图(state machine diagram)、活动图(activity diagram)、定时图(timing diagram)、交互概观图(interactive overview diagram)。
用例图:用于描述系统提供的系列功能,每个用例代表系统的一个功能模块。主要在需求分析阶段使用,用于描述系统实现的功能。
类图:表示系统中应该包含哪些实体,各实体之间如何关联,它显示了系统的静态结构。
类图除了可以表示实体的静态内部结构之外,还可以表示实体之间的相互关系。类之间有三种基本关系:关联(包括聚合、组合);泛化(与继承同一个概念);依赖。
关联:
关联具有一定的方向性,如果仅能从一个类单方向的访问另一个类,称为单向关联;如果两个类可以互相访问对象,则称为双向关联。一个对象能访问关联对象的数目被称为多重性。在很多时候,关联和属性很像,其关键区别在于类里的某个属性引用到另外一个实体时,则变成了关联。
关联关系包括两种特例:聚合和组合它们都有部分和整体的关系,但通常认为组合比聚合更严格,当某个实体聚合成另一个实体时,该实体还可以同时是另一个实体的部分。
泛化:
泛化与继承是同一个概念都是指子类是一种特殊的父类。还有一种与继承类似的关系,类实现接口可视为一种特殊的继承。
依赖:
如果一个类的改动会导致另一个类的改动,则称两个类之间存在依赖关系。依赖的常见原因有:改动的类将消息发送给另一个类;改动的类以另一个类作为数据部分;改动的类以另一个类作为操作参数。通常而言,依赖是单向的。
组件图:
对于现代的大型应用程序而言,通常不只是单独一个类或单独一组类能完成的,通常会由一个或多个可部署的组件组成。对于Java程序而言,可复用的组件通常打包成一个JAR、WAR等文件;对于C/C++应用而言,可复用的组件通常是一个函数库,或者是一个DLL(动态链接库)文件。组件图提供系统的物理视图,它的用途是显示系统中的软件对其他软件组件(例如库函数)的依赖关系。
部署图:
部署图用于描述软件系统如何部署到硬件环境中,他的作用是显示软件系统不同的组件将在何处物理运行,以及它们将如何彼此通信。
顺序图:
顺序图显示具体用例(或者是用例的一部分)的详细流程,并且显示流程中不同对象之间的调用关系,同时还可以详细的显示对不同对象的不同调用。顺序图描述了对象之间的交互(顺序图和通信图都被称为交互图),重点在于描述消息及其时间顺序。
顺序图有两个维度:垂直维度,已发生的时间顺序显示消息/调用的序列;水平维度,显示消息被发送到的对象实例。顺序图的关键在于对象之间的消息,对象之间的信息传递就是所谓的消息发送,消息通常表现为对象调用另一个对象的方法或方法的返回值。
与顺序图类似的还有通信图(以前也被称作协作图),通信图同样可以描述对象之间的交互关系,但通信图没有精确的时间概念。一般来说,通信图可以描述的内容,顺序图都可以描述。
活动图:
活动图和状态机图都被称为演化图。活动图用于描述用例内部的活动或方法的流程,如果除去活动图中的并行活动描述,它就变成了流程图。状态机图描述某一对象生命周期中需要关注的不同状态,并会详细描述刺激对象状态改变的事件,以及对象状态改变时所采取的动作。
演化图的5要素:状态、事件、动作、活动、条件。
对于激发对象状态改变的事件有两种类型:内部事件、外部事件。
状态机图:
状态机图表示某个对象所处的不同状态和该类的状态转换信息。状态机图的符号集包括5个基本元素:初始状态、状态之间的转换、状态、判断点、一个或多个终止点。
Java的面向对象特征:
Java是纯粹的面向对象编程语言,完全支持面向对象的三大基本特征:封装、继承、多态。
“一切都是对象”——在Java中,除了8个基本数据类型值之外,一切都是对象。对象具有状态,一个对象用数据值来描述它的状态。Java通过为对象定义成员变量来描述对象的状态;对象还有操作,这些操作可以改变对象的状态,对象的操作也被称为对象的行为,Java通过为对象定义方法来描述对象的行为。
对象实现了数据和操作的结合,是Java程序的核心,所以Java里的对象具有唯一性,每个对象都有一个标识来引用它,如果某个对象失去了标识,这个对象将变成垃圾,只能等着垃圾回收机制回收它。Java语言不允许直接访问对象,而是通过对对象的引用来操作对象。
对象的抽象化是类,类的具体化就是对象,也可以说类的实例是对象。
Java语言使用class关键字定义类,定义类时使用成员变量描述该类对象的数据,使用方法描述该类对象的行为特征。
类之间有两种主要的结构关系:
一般-特殊关系:是典型的继承关系,使用extends关键字来表示“is a”关系
整体-部分结构关系:也被称为组装结构,是典型的组合关系。Java通过在一个类里保存另一个对象的引用来实现这种关系,其实是一种“has a”关系
开发者定义了Java类之后,就可以使用new关键字来创建指定类的对象了。