合成的語法(初始化)


就以前的學習情況來看事實已進行了多次合成操作爲進行合成只需在新類裏
簡單地置入對象引用即可舉個例子來說假定要在一個對象裏容納幾個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 使所有字段在使用前都獲得正確的初始化
 
發佈了27 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章