在一个新类的定义中使用其他对象。这就是组合(composition)。组合是在Java中实现程序复用(reusibility)的基本手段之一。

 

组合与"has-a"

一个对象是另一个对象的数据成员。比如我们看之前提到的充电电筒的例子:

一个充电电筒中的电池、LED灯、按钮…… 都可以是一个对象。我们可以定义一个Battery类来定义和产生电池对象。而在充电电筒的类定义中,可以用一个电池对象作为其数据成员,来代表电池部分的状态。

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

class Battery{
    public void chargeBattery(double p){
        if(this.power < 1.){
            this.power = this.power + p;
        }
    }
    public boolean useBattery(double p){
        if(this.power >= p){
            this.power = this.power - p;
            return true;
        }else{
            this.power = 0.0;
            return false;
        }
    }
    private double power = 0.0;
}
class Torch{
    public void turnOn(int hours){
        boolean usable;
        usable = this.theBattery.useBattery(houts*0.1);
        if(usable != true){
            System.out.println("No more usable,must charge!");
        }
    }
    public void charge(int hours){
        this.theBattery.chargeBattery(hours*0.2);
    }
    private Battery theBattery = new Battery();
}

上面的new为theBattery对象分配内存,不可或缺。

我们定义Battery类。Torch类使用了一个Battery类型的对象(theBattery)来作为数据成员。在Torch的方法中,我们通过操纵theBattery对象的接口,来实现Battery类所提供的功能(functionality)。

has-a: 手电有电池 (注意上面的菱形连线)

通过组合,我们可以复用Battery相关的代码。假如我们还有其他使用Battery的类,比如手机,计算器,我们都可以将Battery对象组合进去。这样就不用为每个类单独编写相关功能了。

我们可以增加一个Test类,看看实际效果:

public class Test{
    public static void main(String[] args){
        Torch aTorch = new Torch();
        System.out.println("Charge : 2 hours");
        aTorch.charge(2);
        System.out.println("First Turn On : 3 hours");
        aTorch.turnOn(3);
        System.out.println("Second Turn On : 3 hours");
        aTorch.turnOn(3);
    }
}

上面程序的运行结果:

Charge: 2 hours
First Turn On: 3 hours
Second Turn On: 3 hours
No more usable, must charge!

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

基本类型

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

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

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

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

Java基础06 组合(转载)的更多相关文章

  1. Java基础06 组合

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经尝试去定义类.定义类,就是新建了一种类型(type).有了类,我们接着构造 ...

  2. Java基础--定时任务Timer(转载)

    Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...

  3. Java基础—反射(转载)

    转载自: JAVA反射与注解 JAVA反射 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射机制是什么 反射 ...

  4. JAVA基础知识点(转载的)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/8846697 1.使用浮点型数值时,默认的类型是double,后面加上f或F才被识别为flo ...

  5. Java基础—注解(转载)

    概念 注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面 ...

  6. Java基础—数组(转载)

    Java 语言中提供的数组是用来存储固定大小的同类型元素.其实数组就是一个容器. 创建数组 Java 中声明数组的语法有两种: dataType[] arrayRefVar; // 首选的方法 dat ...

  7. Java基础—内部类(转载)

    转载自:java中的匿名内部类总结 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部 ...

  8. Java基础—运算符(转载)

    转载自:Java运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运 ...

  9. java基础06 IO流

    IO用于在设备间进行数据传输的操作. Java IO流类图结构:   IO流分类 字节流: InputStream FileInputStream BufferedInputStream Output ...

随机推荐

  1. 解决sqlite删除数据后,文件大小不变问题 转载

    原文地址:http://blog.csdn.net/yangchun1213/article/details/7656146   说了这么多,没进主题,我的主题是给Sqlite在删除数据后擦屁股. 大 ...

  2. android加密解密完美教程

    经常使用加密算法:DES.3DES.RC4.AES,RSA等; 对称加密:des,3des,aes 非对称加密:rsa 不可逆加密:md5 加密模式:ECB.CBC.CFB.OFB等; 填充模式:No ...

  3. 建立DB-LINK和建立视图

    在系统数据通信间经常会有数据库的数据直接引用,使用视图VIEW的方式实现.视图调用通常会有两种情况,一种是同一数据库的视图,一种是跨数据库的视图. 在同一数据库地址不同用户下,不过不同的用户视图调用需 ...

  4. Less资源汇总

    GUI编译工具 为方便起见,建议初学者使用GUI编译工具来编译.less文件,以下是一些可选GUI编译工具: koala(Win/Mac/Linux) 国人开发的LESSCSS/SASS编译工具.下载 ...

  5. solr6.6 配置拼音分词

    参考:solr6.6 配置同义词 1.下载拼音分析包 下载地址:pinyin.zip 解压后放在core下面的lib文件夹下面: 2.修改managed-schema配置文件 <fieldTyp ...

  6. 总结对Docker这个东西的想法

    记得一开始的时候,还只能在一些网站上看到关于Docker零星的一些消息,之后的不久,有关Docker消息就遍布网络. 是什么因素让Docker火起来的? 或者说什么原因促使大家都对Docker感兴趣并 ...

  7. WPF动画制作简单的按钮动画

    主界面的代码 <StackPanel ButtonBase.Click="Grid_Click"> <Button Content="逐渐变大缩小&qu ...

  8. 云计算之路-阿里云上-十字路口:阿里云SLB故障

    2013年7月24日,18:20~18:50左右,处于阿里云云服务最前沿的SLB(负载均衡)出现故障,造成了网站不能正常访问(由于是最前沿,这次连502也看不到了). 在大家对昨日RDS故障带来的麻烦 ...

  9. 怎样优化cocos2d/x程序的内存使用和程序大小

    再次感谢原创者:Steffen Itterheim.原创博客原文地址: http://www.learn-cocos2d.com/2012/11/optimize-memory-usage-bundl ...

  10. (转)C的代码是如何变成程序的

    原文链接:http://blog.csdn.net/fz_ywj/article/details/8769825 C语言是一门典型的编译语言,源代码文件需要编译成目标代码文件才能运行.可以认为程序文件 ...