复杂类的设计
通过分解与复合,可以简化复杂类的设计与实现,使代码易于维护。在特定的情况下,还可以通过继承和接口来简化复杂类的设计。
举个例子,在一个猪八戒吃西瓜的游戏中,需要定义一个叫做猪八戒的类。因为有了这个之后我们就可以创建各种各样的猪八戒的对象了,但是想一下子把猪八戒这个类设计出来比较困难,为了简化这个问题,我们可以常常把猪八戒分成猪头猪腿猪身子等若干部分。
,而猪头又可以分为猪眼睛猪耳朵猪鼻子等几个部分,只要在游戏中把上述各个部分制造好了,再把它们进行复合,便可以构成主类。此外,还可以定义一个西瓜类,那么猪八戒吃西瓜的行为就可以简化啦。只要在猪八戒类体中定义一个名为“吃”的对象方法,参数设置为西瓜类的变量。由此可见,使用分解与复合方法,可以实现复杂类的设计。此外,在特定的情况下,还可以通过继承和接口来简化复杂类的设计。(接口和继承我们后面介绍。)
关于分解与复合方法,关键就是:
以一个圆柱体的设计为例。
圆柱体:
-
由底面和高确定。
-
底面和高是其数据成员,而底面是一个圆形对象,是一个Circle类型的成员变量。
那么圆柱体类就可以通过上述的分解与复合方法进行设计,看代码:
package com.oop;
import java.util.Scanner;
//主类
public class complex {
public static void main(String[] args) {
float r,h;
Scanner sc = new Scanner(System.in);
System.out.println("输入圆柱体底面半径:");
r = sc.nextFloat();
System.out.println("输入圆柱体高:");
h = sc.nextFloat();
Cylinder c = new Cylinder(new Circle(r),h);
System.out.println("圆柱体表面积为"+c.getSurfaceArea());
System.out.println("圆柱体体积为"+c.getVolume());
}
}
//圆柱体类
class Cylinder {
Circle bottom;
float height;
Cylinder(Circle b,float h){
bottom = b;
height = h;
}
//求体积
float getVolume(){
return bottom.getArea()*height;
}
//求表面积
float getSurfaceArea(){
float res = (float)(2*bottom.getArea());
res += bottom.getPerimeter()*height;
return res;
}
}
//圆形类
class Circle {
float radius;
Circle(float r){
radius = r;
}
//求周长
float getPerimeter(){
float res = (float) (2*Math.PI*radius);
return res;
}
//求面积
float getArea(){
return (float)Math.PI*(float)Math.pow(radius,2);
}
}
UML图表示——
UML(Uniform Modeling Language):统一建模语言
- 一种标准,可用于描述类自身的结构以及多个类之间的关系。
- 是面向对象程序开发人员之间的一种技术交流工具。
我们先来看看类结构的UML图表示方法:
输入参数可以是:
- 简单数据类型参数
- 引用类型:该方法返回后,不会改变所引用的对象的属性
输出参数:该参数一定只能是引用类型的参数。
输出参数表示该方法会修改该参数所引用对象的属性或所引用数组元素的值,且该方法不会访问所引用的对象变量的属性。
双向参数:该参数类型必须为引用类型。
方法内部会读取参数所引用的对象的属性值,并对其进行修改。
至此,你就可以读懂一个类的结构啦!那么我们如何表示类之间的关系呢?类之间的关系从亲密到疏远可以细分为六种——
(1) 继承
(2) 实现
(3) 组合
(4) 聚合
(5) 关联
(6) 依赖
在UML图中如何表示这几种关系呢?如下图,所有关系,都用一条有向线段表示,线段两端分别连接两个类的UML图。
组合关系中,部分类的对象是整体类对象中不可分割的一部分。整体类对象存在,作为其一部分的部分类对象随之产生,整体类对象消亡,作为其一部分的部分类对象随之消亡。例如人的大脑和人就是组合关系。
组合关系在代码层面的特点:部分类以对象的数据成员的形式存在于整体类中。
-
- 当整体类对象创建成功后,作为其组成的一部分的部分类对象也随之创建。
-
- 整体类对象消亡,其组成的一部分的部分类对象也随之消亡。
聚合关系中,部分类的对象是整体类的对象的一部分,但它们之间可以相互分离。例如人的衣着和人就是聚合关系。
聚合关系在代码层面的特点:部分类以对象或类的数据成员的形式出现在整体类中。
-
- 整体类对象消亡了,作为其属性的部分类的对象不一定消亡。
-
- 整体类对象产生了,作为其属性的部分类的对象也不一定随之产生。
关联关系在代码层面的特点与聚合关系一样。
但在语义方面:引用类对象和被引用类对象之间不存在部分和整体的关系。
依赖关系,用一个带箭头的虚线表示,箭头指向被引用的类,表示引用类仅仅在定义某若干成员方法成员时,“利用了”被引用的类。
在代码层面上的特点:引用类在定义方法时,方法的参数类型为被引用类类型,或者方法内部使用了被引用类。
例如下图,猪八戒这个类中的这个吃西瓜的方法由于方法参数的数据类型西瓜类,因此猪八戒和西瓜是一个依赖关系,猪八戒依赖于西瓜。
此外,若一个类和另一个类具有两种关系,不需要把两种关系都表示出来,只需要保留较为亲密的那个关系就可以了。
下面我们看一下例子,理解一下两个类之间关系的表示。