编程语言 | Java - 02.理解面向对象

1.面向对象的特征

结构化程序设计简介

  结构化程序设计方法主张按功能来分析系统需求,其主要原则可概括为自顶向下,逐步求精,模块化等。结构化程序设计首先采用结构化分析(Structrued Analysis,即SA)方法对系统进行需求分析,然后使用结构化设计(Structrued Design,即SD)方法对系统进行概要设计、详细设计,最后采用结构化编程(Structrued Program,即SP)方式来实现系统。使用这种SA、SD和SP的方式可以较好的保证软件系统的开发进度和质量。
  因为结构化程序设计方法主张按功能把软件系统逐步细分,因此这种方法也被成为面向功能的程序设计方法;结构化程序设计的每个功能都负责对数据进行一次处理,每个功能都接受一些数据,处理完后输出一些数据,这种处理方式也被称为面向数据流的处理方式。
  结构化程序设计里最小的程序单元是函数,每个函数都负责完成一个功能,用以接受一些输入数据,函数对这些输入数据进行处理,处理结束后输出一些数据。整个软件系统由一个个函数组成,其中作为程序入口的函数被称为主函数,主函数依次调用其他函数,普通函数之间依次调用,从而完成整个软件系统的功能。

编程语言 | Java - 02.理解面向对象
结构化软件的逻辑结构示意图

结构化程序设计的局限性

  1、设计不够直观,与人类习惯思维不一致。采用结构化程序分析、设计时,开发者需要将客观世界模型分解成一个一个功能,每个功能用以完成一定的数据处理。
  2、适应性差,可扩展性不强。由于结构化设计采用自顶而下的设计方式,所以当用户的需求发生改变,或需要修改现有的实现方式时都需要自顶而下地修改模块结构,这种方式的维护成本相当大。

程序的三种结构

  结构化程序设计非常强调实现某个功能的算法,而算法的实现过程是由一系列操作组成的,这些操作之间的执行次序就是程序的控制结构。1996年,计算机科学家Bohm和Jacopini证明了这样的事实:任何简单或复杂的算法都可以由三种结构组成:顺序结构、选择结构、循环结构,这三种结构就被称为程序设计的三种基本结构,也是结构化程序设计必须采用的结构。

编程语言 | Java - 02.理解面向对象
顺序结构
编程语言 | Java - 02.理解面向对象
选择结构
编程语言 | Java - 02.理解面向对象
循环结构

面向对象程序设计

  面向对象是一种更优秀的的程序设计方法,它的基本思想是使用类、对象、继承、封装,消息等基本概念来进行程序设计。它是从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以现实世界中的事物(即对象)为中心来思考问题,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的类,作为系统的基本构成单元(而不是用一些与现实世界中的事物相关比较远,并且没有对应关系的其它过程来构造系统),这使得系统可以直接映射客观世界,并保持客观世界中事物及其相互关系的本来面貌。
  如果采用面向对象方式开发的软件系统,其最小的程序单元是类,这些类可以生成系统中的多个对象,而这些对象则直接映射成客观世界的各种事物。

编程语言 | Java - 02.理解面向对象

面向对象的特征

  面向对象方法具有三个基本特征:继承(Inheritance)、封装(Encapsulation)和多态(Polymorphism)
    继承:是面向对象实现软件复用的重要手段,当子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法。
    封装:指的是将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能。
    多态:指的是子类对象可以直接赋给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时,可以表现出多种行为特征。

面向对象还支持的功能

  1、对象是面向对象方法中最基本的概念,它的基本特点有:标识惟一性、分类性、多态性、封装性、模块独立性好。
  2、类是具有共同属性、共同方法的对象的集合。类是对象的抽象;对象则是类的实例。而类是整个软件系统最小的程序单元,类的封装性将各种信息细节隐藏起来,并通过公用方法来暴露该类对外所提供的功能,从而提高了类的内聚性,降低了对象之间的耦合性。
  3、对象间的这种相互合作需要一个机制协助进行,这样的机制称为“消息”。消息是一个实例与另一个实例之间传递的信息。
  4、在面向对象方法中,类之间共享属性和操作的机制称为继承。已有的类可当作基类来引用,则新类相应地可当作派生类来引用。继承具有传递性。可分为单继承(一个继承只允许有一个直接父类,即类等级为树形结构)与多继承(一个类允许有多个直接父类)。


2.UML(统一建模语言)

编程语言 | Java - 02.理解面向对象
UML发展历史
编程语言 | Java - 02.理解面向对象
UML2.0的组成

用例图

  用例图用于描述了系统提供的系列功能,而每个用例则代表系统的一个功能模块。用例图的主要目的是帮助开发团队以一种可视化的方式理解系统的需求功能,用例图对系统的实现不做任何说明,仅仅是系统功能的描述。
  用例图主要在需求分析阶段使用,用于与客户交流,保证系统需求的无二性,用例图表示系统外观,不要指望用例图和系统内部的各个类之间有任何联系。不要把用例做得过多,过多的用例将导致难以阅读,难以理解;尽可能多地使用文字说明。

编程语言 | Java - 02.理解面向对象
用例图

类图

  类图是最古老、功能最丰富,使用最广泛的UML图型,类图表示系统中应该包含哪些实体,各实体之间如何关联;换句话说,它显示了系统的静态结构,类图可用于表示逻辑类,逻辑类通常就是业务人员所谈及的事物种类。

编程语言 | Java - 02.理解面向对象
类图中类的表示方法

  类图除了可以表示实体的静态内部结构之外,还可以表示实体之间的相互关系,类之间有三种基本关系:关联(包括聚合,组合)、泛化(与继承同一个概念)、依赖。

编程语言 | Java - 02.理解面向对象
类之间的关联关系
编程语言 | Java - 02.理解面向对象
类之间的继承关系
编程语言 | Java - 02.理解面向对象
JTable和DefaultTableModel之间的依赖关系

组件图

  对于现代的大型应用程序而言,通常不只是单独一个类或单独一组类所能完成的,通常会由一个或多个可部署的组件组成。对Java程序而言,可复用的组件通常打包成一个JAR、WAR等文;对C/C++应用而言,可复用的组件通常是一个函数库,或者一个DLL(动态链接库)文件。
  组件图提供系统的物理视图。它的用途是显示系统中的软件对其他软件组件(例如,库函数)的依赖关系。组件图可以在一个非常高的层次上显示,从而仅显示粗粒度的组件,也可以在组件包层次上显示。

编程语言 | Java - 02.理解面向对象
组件与接口
编程语言 | Java - 02.理解面向对象
组件图

部署图

  部署图用于描述软件系统如何部署到硬件环境中。它的用途是显示软件系统不同的组件将在何处物理地运行,以及它们将如何彼此通信。
  因为部署图是对物理运行情况进行建模,所以系统的生产人员就可以很好地利用这种图来安装、部署软件系统。

编程语言 | Java - 02.理解面向对象
部署图

顺序图

  顺序图显示具体用例(或者是用例的一部分)的详细流程,并且显示了流程中不同对象之间的调用关系,同时还可以很详细地显示对不同对象的不同调用。顺序图描述了对象之间的交互(顺序图和通信图都被称为交互图),重点在于描述消息及其时间顺序。
  顺序图有两个维度:垂直维度以发生的时间顺序显示消息/调用的序列;水平维度显示消息被发送到的各对象实例。顺序图的关键在于对象之间的消息,对象之间的的信息传递就是所谓的消息发送,消息通常表现为对象调用另一个对象的方法,或方法的返回值,发送者和接收者之间的箭头表示消息。

绘制顺序图

  顺序图的绘制非常简单。顺序图的顶部每个框表示每个类的实例(对象),在框中,类实例名称和类名称之间用冒号或空格来分隔,例如,myReportGenerator:ReportGenerator。如果某个类实例向另一个类实例发送一条消息,则绘制一条具有指向接收类实例的开箭头的连线,并把消息/方法的名称放在连线上面。
  对于某些特别重要的消息,我们还可以绘制一条带箭头的、指向发起类实例的虚线,将返回值标注在虚线上,绘制带返回值的信息可以使得序列图更易于阅读。下图显示了用户登陆的的顺序图。

编程语言 | Java - 02.理解面向对象
用户登录顺序图

演化图

  活动图和状态机图都被称为演化图,其实区别和联系如下:
    1、活动图:用于描述用例内部的活动或方法的流程,如果去除活动图中的并行活动描述以后,它就变成流程图。
    2、状态机图:描述某一对象生命周期中需要关注的不同状态,并会详细描述刺激对象状态改变的事件,以及对象状态改变时所采取的动作。

演化图的五要素

  1、状态:状态是对象响应事件前后的不同面貌,状态是某个时间段对象所保持的稳定态,目前的软件计算都是基于稳定态的,对象的稳定态是对象的固有特征,一个对象的状态一般是有限的。有限状态的对象是容易计算的,对象的状态越多,对象的状态迁移越复杂,对象状态可以想象成对象演化过程中的快照。
  2、事件:来自对象外界的刺激,通常的形式是消息的传递,只是相对对象而言发生了事件。事件是对象状态发生改变的原动力。
  3、动作:动作是对象针对所发生事件所作的处理,实际上通常表现为某个方法被执行。
  4、活动:活动是动作激发的后续系统行为。
  5、条件:条件指事件发生所需要具备的条件。

对于激发对象状态改变的事件,通常有两种类型

  1、内部事件:从系统内部激发的事件,一个对象的方法(动作)调用,(通过事件**)另一个对象方法(动作)。
  2、外部事件:从系统边界外的激发的事件,例如用户的鼠标、键盘动作。

活动图

  活动图主要用于描述过程原理、业务逻辑以及工作流的技术,很多情况下,活动图与传统的流程图非常相似,区别是活动图支持并发。活动图非常类似于传统的流程图,它也使用圆角矩形表示活动,使用带箭头的实线表示事件。
  绘制活动图时以活动为中心,整个活动图只有一个开始活动,可以有多个结束活动,活动图需要将并行活动和串行活动的分离,遇到分支和循环时最好像传统流程图将分支、循环条件明确表示。活动图最大优点在于支持并行行为,并行对于工作流建模和过程建模非常重要。因为有了并行,因此需要进行同步,同步通过汇合来指明。

编程语言 | Java - 02.理解面向对象
活动图

状态机图

  状态机图表示某个类所处的不同状态和该类的状态转换信息。实际上我们很少绘制状态机图,我们只对“感兴趣的” 类绘制状态机图。也就是说,在系统活动期间具有三个或更多潜在状态的类才需要考虑使用状态机图进行描述。
  状态机图的符号集包括5个基本元素:
    1)初始状态,它使用实心圆来绘制;
    2)状态之间的转换,它使用具有开箭头的线段来绘制;
    3)状态,它使用圆角矩形来绘制;
    4)判断点,它使用空心圆来绘制;
    5)一个或者多个终止点,它们使用内部包含实心圆的圆来绘制。

  绘制状态机图时应该保证对象只有一个初始状态,可以有多个终结状态。状态要表示对象的关键快照,有重要的实际意义,无关紧要的状态则无需考虑,绘制状态机图时事件和方法要明确。

编程语言 | Java - 02.理解面向对象
状态机图


3.Java的面向对象特征

一切都是对象

  在Java语言中,除了8个基本数据类型值之外,一切都是对象。而对象就是面向对象程序设计的中心。对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
  对象具有状态,一个对象用数据值来描述它的状态。Java通过为对象定义Field(以前常被称为属性,现在也称为字段)来描述对象的状态;对象还有操作,这些操作可以改变对象的状态,对象的操作也被称为对象的行为,Java通过为对象定义方法来描述对象的行为。
  对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。

类和对象

  具有相同或相似性质的 一组对象的抽象就是类,类是对一类事物描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称实例(instance)。
  对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类是用来描述一系列对象,类概述每个对象应包括的数据,类概述每个对象的行为特征。因此我们可以把类理解成某种概念、定义,它规定了某类对象所共同具有的数据和行为特征。
  Java语言使用class关键字定义类,Java允许开发者自由定义类,定义类时可使用Field来描述该类对象的数据,可使用方法来描述该类对象的行为特征。

类之间主要结构

  一般—>特殊结构:也被称为分类结构,这种分类结构关系就是典型的继承关系,Java语言使用extends关键字来表示这种分类结构,Java的子类是一种特殊的父类。因此这种一般——特殊的结构关系其实是一种“is a”关系。
  整体—>部分结构:也被称为组装结构,这种分类关系就是典型的组合关系,Java语言通过在一个类里保存另一个对象的引用来实现这种组合关系,因此这种整体——部分结构关系其实是一种“has a”关系。