假設,如果,要是,'靜態變量'的繼承能夠按照我‘天真的以為是的那個樣子’,會怎麼樣呢?
[java]
class Person {
public static String name = "person";
public static String name(){
return name;
}
}
class Person2 extends Person {
}
class Person3 extends Person {
}
Person2 和 Person3 都繼承自Person.
接著我希望如此:
[java]
public class Test {
public static void main(String[] args) {
Person2.name = "person2";
Person3.name = "person3"
Person.name();//希望能打印出 "person"
Person2.name();//希望能打印出 "person2"
Person3.name();//希望能打印出 "person3"
}
}
但是最後都打印瞭出person3.總結一句:
靜態變量和靜態方法是完全特定屬於某個類的。繼承自父類的類訪問到的靜態變量也是它父親的。你可以申明自己的靜態變量覆蓋父類的靜態變量,但是如果你用的是繼承自父類的靜態方法獲取靜態變量,你最終得到的也是父類的靜態變量。
這是完全操蛋的設計!!!
繼承就應該是繼承到父類的一份copy!
為什麼我強烈的希望繼承的是copy 而不是一個簡單引用呢?
因為它讓java的某種申明式語法成為不可能。
下面全部是基於靜態變量和方法繼承後在子類會獲得一份新的copy的假設而成立的(這實際上是不被支持的),千萬不要以為下面的例子是正確的
舉個例子,我在設計一個模型類的時候:
[java]
public class Document {
protected static String storeIn = "";
public static void storeIn(String name){
storeIn = name;
}
public static String storeIn(){
return storeIn;
}
…….
}
public class Person extends Document {
static {
storeIn("persons");
hasMany("addresses", new Options(map(
Options.n_kclass, Address.class,
Options.n_foreignKey, "person_id"
)));
}
}
每個子類可以通過靜態變量存儲的自己的配置信息。通過繼承自父類從而避免每次去申明這些靜態變量和方法。看出端倪瞭嗎?靜態變量完全可以作為一個類似Annotation的東西,並且會比Annotation更簡單。Annotation是啥,就是對某個類(域,方法等)進行註解,對嗎?
上面Person的寫法完全等價於:
[java]
@StoreIn("persons")
public class Person extends Document {
@HasMany(Options.n_kclass=Address.class)
private List addresses;
…..
}
第一眼感覺上都差不多。但是Annotation存在諸多限制,比如裡面不能存復雜類型的信息。而且一旦寫瞭,就寫死啦,就不能改啦。那如果使用靜態變量呢?
我要那storeIn的信息怎麼拿?
[java]
Person.storeIn();
//annotation的拿法
Person.getClass.getAnnotations()
….blablalba…好多。
然後程序在運行的時候完全可以修改靜態變量的值。如果你覺得不安全,你還可以通過final 進行限制。
其實剛才說瞭那麼多,還有一個點子沒說到,就是,靜態變量都是繼承自父類的,你沒必要在子類像Annotation一個一個去寫。對一個類的註解信息你完全就像調用一個簡單的方法進行設置。多爽。
但是現在因為剛才我說的Java糟糕的靜態繼承設計,使得這成為不可能。不然,還需要Annotation嗎?需要!但完全可以隻作為靜態變量的一個補充。