合成的语法(初始化)


就以前的学习情况来看事实已进行了多次合成操作为进行合成只需在新类里
简单地置入对象引用即可举个例子来说假定要在一个对象里容纳几个String 对象两种
原始数据类型以及属于另一个类的一个对象对于非基类型的对象来说只需将引用置于新
类即可但对原始数据类型来说则需直接定义
//: c06:SprinklerSystem.java
// Composition for code reuse.
class WaterSource {
private String s;
WaterSource() {
System.out.println("WaterSource()");
s = new String("Constructed");
}
public String toString() { return s; }
}
public class SprinklerSystem {
private String valve1, valve2, valve3, valve4;
WaterSource source;
int i;
float f;
void print() {
System.out.println("valve1 = " + valve1);
System.out.println("valve2 = " + valve2);
System.out.println("valve3 = " + valve3);
System.out.println("valve4 = " + valve4);
System.out.println("i = " + i);
System.out.println("f = " + f);
System.out.println("source = " + source);
}
public static void main(String[] args) {
SprinklerSystem x = new SprinklerSystem();
x.print();
}
} ///:~
WaterSource 内定义了一个非常特殊的方法toString() 大家不久就会知道每种非基
类型的对象都有一个toString()方法若编译器本来希望得到的是一个String 但却获得了这
样的一个对象便会调用这个方法所以在下面这个表达式中
System.out.println("source = " + source);
编译器会发现我们试图向一个WaterSource 添加一个String 对象"source =" 这对它
来说是不可接受的因为我们只能将一个字串添加到另一个字串所以它会说我要
调用toString() 把source 转换成字串经这样处理后它就能编译两个字串并将结果字
串传递给一个System.out.println() 每次想让自己的一个类允许这样的行为都只需写一个
toString()方法
如果不深究可能会草率地认为编译器会为上述代码中的每个引用都自动构造对象由
于Java 一贯具有安全和谨慎的形象例如可能以为它会为WaterSource 调用默认构造函
数以初始化source 然而打印语句的输出事实是
valve1 = null
valve2 = null
valve3 = null
valve4 = null
i = 0
f = 0.0
source = null
在类内作为字段使用的基本数据会初始化成零就象第2 章指出的那样但对象引用会
初始化成null 而且假如试图为它们中的任何一个调用方法就会产生一个违例这种
结果实际是相当好的而且很有用我们可在不掷出一次违例的前提下仍然把它们
打印出来
编译器并不只是为每个引用创建一个默认对象因为那样在许多情况下都会带来不必要
的开销如希望引用得到初始化可在下面这些地方进行
(1) 在对象定义的时候这意味着它们在构造函数调用之前肯定能得到初始化
(2) 在那个类的构造函数中
(3) 就在真正使用对象之前这通常叫作暂缓初始化它可减少不必要的开销
只要对象并不需要每次都创建
下面向大家展示了所有这三种方法
//: c06:Bath.java
// Constructor initialization with composition.
class Soap {
private String s;
Soap() {
System.out.println("Soap()");
s = new String("Constructed");
}
public String toString() { return s; }
}
public class Bath {
private String
// Initializing at point of definition:
s1 = new String("Happy"),
s2 = "Happy",
s3, s4;
Soap castille;
int i;
float toy;
Bath() {
System.out.println("Inside Bath()");
s3 = new String("Joy");
i = 47;
toy = 3.14f;
castille = new Soap();
}
void print() {
// Delayed initialization:
if(s4 == null)
s4 = new String("Joy");
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
System.out.println("s3 = " + s3);
System.out.println("s4 = " + s4);
System.out.println("i = " + i);
166 Java 编程思想
System.out.println("toy = " + toy);
System.out.println("castille = " + castille);
}
public static void main(String[] args) {
Bath b = new Bath();
b.print();
}
} ///:~
请注意在Bath 构造函数中语句会在任何初始化进行之前得以执行如果未在定义时
便进行初始化那么在将一条消息发给一个对象引用之前仍然不能保证会进行任何初始化
操作除了不可避免的运行时间违例
下面是该程序的输出
Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed
调用print( )时它会填充s4 使所有字段在使用前都获得正确的初始化
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值