66.
class Base {
public String className = "Base";
}
class Derived extends Base {
private String className = "Derived";
}
public class PrivateMatter {
public static void main(String[ ] args) {
System.out.println(new Derived().className);
}
}
不知道大師出於何種考慮,本章又回到了語言機制本身,結果挺明顯,編譯不通過,因爲Derived的className域是private,都知道父子類方法簽名都相同會發生override,但父子類的field名稱相同,則會發生hide,把private改成public會ok並打印Derived,但和方法的override完全不是一回事
總結:hide和overload,override不同,是面向對象中一種代表設計錯誤的機制,不要依賴這樣的機制
67.
public class Test {
public static void main(String[] args) {
String s = new String("Hello world");
System.out.println(s);
}
}
class String {
private final java.lang.String s;
public String(java.lang.String s) {
this.s = s;
}
public java.lang.String toString() {
return s;
}
}
挺有意思的一條,看着挺玄乎的,結果是運行時Error,找不到main入口方法,原因是自定義的String類優先於默認加載的java.lang.String,其實把main(String[] args)改成main(java.lang.String[] args)可以搞定
總結:本條看似娛樂,本質確有意義,定義類名時注意不要用java.lang包裏面的,這是現實確實會發生的事情
68.
public class Test {
println(X.Y.Z);
}
class X {
static class Y {
static String Z = "Black";
}
static C Y = new C();
}
class C {
String Z = "White";
}
這個比上條還有意思,是內部類名稱Y優先,還是引用變量名稱Y優先?答案是White,引用變量名稱Y優先,這種比hide現象還難出現的現象稱作obscure,這裏變量名將優先於類型名
總結:因爲這裏的例子達成前提是C類型的引用變量Y名稱是大寫的,所以如按照語言大小寫規範來命名,可完全杜絕obscure現象
69.繼68條後繼續擴展討論,第一次看到了內部類的extends用法,別的沒什麼深刻的印象
70.很簡單的一條,兩個位於不同包,又被default修飾方法,就算方法簽名一樣也不會發生override
71.
import static java.util.Arrays.toString;
public class Test {
public static void main(String... args) {
printArgs(1, 2, 3, 4, 5);
}
static void printArgs(Object... args) {
System.out.println(toString(args));
}
}
結果是編譯不通過,編譯器選擇的是調用由Object繼承而來的Object.toString(),這種由於static import功能帶來的同名方法衝突,稱作shade,和68條中的obscure不同之處在於shade是同類型名稱衝突(如方法和方法),而obscure指的是不同類型的名稱衝突(如類名和域名)
總結:事實上static import功能現實中應用很少,不要因爲耍帥來使用它
72.
class Jeopardy {
public static final String PRIZE = "$64,000";
}
public class DoubleJeopardy extends Jeopardy {
public static final String PRIZE = "2 cents";
public static void main(String[ ] args) {
System.out.println(DoubleJeopardy.PRIZE);
}
}
相當簡單的一條,根據java的基本知識,final修飾的方法不能被override,但是final修飾的域則只是說明值不能被修改,像例子中就發生了hide,同時這也是一種錯誤的用法
總結:java中的final關鍵字在方法和域中具有不同的意義,這並不是一個好的語言設計方法,但是新版本隨意新增關鍵詞又會對現有應用本身造成極大的破壞影響
73.關於命名衝突的問題,本章重複了很多次,這條也是,在實際中只需要多留心就可以了,過度地區分hide,obscure和shade也沒有什麼太大的意義
74.本書已經寫到了後期,娛樂的性質更多了一些,在<<Effective Java>>中也詳細討論了設計一個equals方法的幾個重要原則
75.本章的最後一條,並沒有什麼實際的意義,得知了1.4和更早的版本,對於三目運算符的要求是更嚴格的,第二,三操作數,強制要求它們至少要有父子類型關係
總結:本章最後還總結了override,overload,hide,shade,obscure的意義,對於後三者,可以適當地去體會它們的區別,就當是增加一些技術詞彙量