假設,如果,要是,'靜態變數'的繼承能夠按照我‘天真的以為是的那個樣子’,會怎麼樣呢?
class Person { public static String name = "person"; public static String name(){ return name; }}class Person2 extends Person {}class Person3 extends Person {}
Person2 和 Person3 都繼承自Person.
接著我希望如此:
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的假設而成立的(這實際上是不被支援的),千萬不要以為下面的例子是正確的
舉個例子,我在設計一個模型類的時候:
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的寫法完全等價於:
@StoreIn("persons")public class Person extends Document { @HasMany(Options.n_kclass=Address.class) private List addresses; .....}
第一眼感覺上都差不多。但是Annotation存在諸多限制,比如裡面不能存複雜類型的資訊。而且一旦寫了,就寫死啦,就不能改啦。那如果使用靜態變數呢?
我要那storeIn的資訊怎麼拿?
Person.storeIn();//annotation的拿法Person.getClass.getAnnotations()....blablalba...好多。
然後程式在啟動並執行時候完全可以修改靜態變數的值。如果你覺得不安全,你還可以通過final 進行限制。
其實剛才說了那麼多,還有一個點子沒說到,就是,靜態變數都是繼承自父類的,你沒必要在子類像Annotation一個一個去寫。對一個類的註解資訊你完全就像調用一個簡單的方法進行設定。多爽。
但是現在因為剛才我說的Java糟糕的靜態繼承設計,使得這成為不可能。不然,還需要Annotation嗎?需要!但完全可以只作為靜態變數的一個補充。