Java-12 – 组合

我们已经尝试去定义类。定义类,就是新建了一种 类型(type) 。有了类,我们接着构造相应类型的对象。更进一步,每个类型还应该有一个清晰的接口(interface) , 供用户使用。我们可以在一个新类的定义中使用其他对象。这就是 组合(composition) 。组合是在Java中实现程序 复用(reusibility)的基本手段之一。

组合与has-a

我们下面定义一个Battery类,并用power来表示其电量。一个Battery的可以充电(chargeBattery)和使用(useBattery)。我们在随后的Torch类定义中使用Battery类型的对象作为数据成员:

上面的new为theBattery对象分配内存,不可或缺。
我们定义Battery类。Torch类使用了一个Battery类型的对象(theBattery)来作为数据成员。在Torch的方法中,我们通过操纵theBattery对象的接口,来实现Battery类所提供的 功能(functionality) 。
我们说,一个Torch对象 拥有(has-a) 一个Battery对象
通过组合,我们可以复用Battery相关的代码。假如我们还有其他使用Battery的类,比如手机,计算器,我们都可以将Battery对象组合进去。这样就不用为每个类单独编写相关功能了。我们可以增加一个Test类,看看实际效果:

上面程序的运行结果:

我们通过组合来使用了电池对象所提供的功能,比如探测电量是否用尽(根据useBattery()的返回值)。


基本类型

我们将int,float, double, boolean等称为 基本类型(primitive type) ,也就是特殊的类。我们可以将一个整数理解称为一个int类型的对象 。int类型可以有赋值、加法、减法等操作接口。普通类型可以视作对基本类型的拓展。我们已经见过了基本类型作为 数据成员 、方法的参数 、 方法的返回值 和方法内部的 自动变量 。自然的,普通类型的对象,比如Battery和Torch类的对象,也都可以用于这些地方。

C语言中,可用的数据类型(基本上)已经预设好,比如int, float。在Java中,我们除了可以用这些预设的数据类型外,还可以通过类来定制自己想要的数据类型,然后通过组合来使用。但基本类型和普通类型还是有所区别的。基本类型经常被使用,且所占据内存空间不大,所以在Java中,为了效率起见,这些基本类型与普通的类型(也就是自定义的类)的内存管理方式不同。比如,基本类型一旦声明就会被分配内存空间,而普通类型需要使用new关键字来分配内存空间。

Java为每个基本类型提供了相应的普通类型。比如int基本类型对应Integer类型。如果将基本类型的对象转成相应的普通类型变量,所谓的基本类型也就成为了一般意义上的类型(不再有内存管理上的不同)。

这样,我们对Java “一切皆对象” 的理念有了更深一步的理解。