1.3 对象和类
面向对象技术是由一系列的概念和原则组成的,而这些概念和原则中的两个最基础、最重要的就是对象和类。
1.3.1 对象
对象(Object)可以是一个实体、一件事、一个名词,也可以是可获得的某种东西,还可以是可想象为有自己标识的任何事物。对象的实体可以是物理存在的、也可能是一个概念,或是软件中的实体。例如,一辆卡车是一个物理上存在的实体;而一个化学反应过程则是一个概念中的实体;数据结构中的一个链表则是软件领域的实体。
结合前面的描述,可以对对象进行一个正式的定义:对象是一个实体,这个实体具有明确定义的边界(Boundary)和标识(Identity),并且封装了状态(State)和行为(Behavior)。这里关于对象的定义有两方面重要特征。
(1)对象具有明确定义的边界和标识。边界意味着对象是一个封装体,通过封装来与其他对象分隔。而标识则表明每一个对象都是唯一的,虽然有时候某个对象的状态有可能与其他对象一样。每个对象都是独一无二的,通过明确的边界与其他对象区分;同时,这个边界应该是研究该对象的用户可以清晰定义的。比如杯子里的一杯水,对于普通用户来说,杯体就是其边界,这一杯水就是一个对象,区别于另外一个杯子里面的一杯水;但对于化学老师来说,如果他/她现在要研究水的分子结构,那这杯水就不是一个对象,而是包括一系列的水分子的对象,甚至还可以进一步包括氢原子、氧原子这样的对象。
(2)对象封装了状态和行为。对象的状态通过对象的属性(Attribute)和关系(Relationship)来表达。在实际应用中,对象的状态反映了现实世界的一系列属性,如属性的值(即与对象有关系的数据)、与其他对象的关系、任意一个时刻的历史状态。而对象的行为通过对象的操作(Operation)、方法(Method)和状态机(State Machine)来表达,它由对象定义的一系列操作来决定。它定义了当其他对象发出请求时,该对象如何反应。
在UML中,对象用矩形框表示,对象的名称写在矩形框内部,并加上下画线。UML中的对象有命名对象和匿名对象之分,如图1-4所示。
图1-4 UML中的对象
图1-4(a)为命名对象,对象的名称为J.Clark,“:”后面为对象所属的类名Professor,表示J.Clark对象是Professor类的一个实例;而图1-4(b)展示的是匿名对象,该对象没有名称,只有所属的类名Professor,表示Professor类的某个对象;图1-4(c)是一个J.Clark对象,没有指定其所属的类,严格来说,这种只有对象名、没有类名的对象是错误的(因为在对象世界中,任何对象都来自类的实例化),但在早期的分析模型中可以使用,说明已知存在这样的一个对象,但尚未最终确定它所属的类。
1.3.2 类
在现实世界中,对象是具体存在的,可以准确反映问题空间的概念。但是,现实世界的对象常常和其他对象很相近。例如,教授都有一些相似的特性(他们做同样的事情,用同样的方式被描述),学生也有相似的特征,课程也有相似的特征等。如果要对每一个对象都进行建模(编程),那会是很繁重的工作,应该只定义一次教授对象、学生对象、课程对象等,在实际需要该对象时再创建出具体的实体。这就是为什么会需要类的原因。
类(Class)就是这一系列对象的抽象描述,这些对象共享相同的属性、操作、关系和语义。与此对应,一个具体的对象是该类的一个实例。由此可见,类是一种抽象,它将相似的实体抽象成相同的概念,这种抽象过程强调相关特征而忽略其他特征。例如,每位教授虽然有不同的特征(如年龄、身高、体重等),但在一个选课系统中,他们所扮演的角色是相同的,在我们只关注这些相同的特征时,他们就属于同一个类。
类抽象的过程就是将具体对象的特征和行为进行参数化,分别用类的属性和操作表示。
◆ 属性代表类的特征或特性,它表达了类所知道的事情。属性的值是某一特定对象的属性值。在类中,属性名必须是唯一的,同时每一个类的实例(即对象,下同)都有为这个类定义的所有属性的值。
◆ 操作代表类知道和做的事情,它用于访问或修改对象的属性值。而对象的行为是由为此对象定义的一系列操作决定的。
对于一个类,其属性和操作并不是固定的,它们取决于类的应用场景,不同的使用目的决定了不同的抽象方式。例如,针对一个汽车类,从销售人员的角度,他只关注型号、价格、颜色、里程数等属性,以及处理客户订单、准备销售合同、加入清单、从清单中删除等操作;而从维修人员的角度,他只关注发动机类型、传动类型、维修记录等属性,以及测试刹车、修理刹车、转动轮胎、检查转速等操作。
类和对象之间是紧密相关的,每一个对象都是某一个类的实例(类是生成对象的模板,类的定义中包含创建和删除对象的操作);而每一个类在某一时刻都有零个或更多个的实例存在。一个类通过一系列操作来定义行为,而该类的所有实例都可以使用在这个类中定义的操作。同时,类定义了使用哪些数据描述属性,每一个实例都需要定义具体的属性值。
在UML中,同样采用矩形框表示类,该矩形框可以划分为3个区域,分别表示类名、属性和操作,如图1-5所示。
图1-5 UML中的类
此外,类是静态的,它的存在、语义和关系在执行前就已经定义好了。而对象是动态的,在程序执行时可以被创建和删除。