當(dāng)類實現(xiàn)接口時嗜暴,接口就充當(dāng)可以引用這個類的實例的類型。因此,類實現(xiàn)了接口姨蟋,就表明客戶端對這個類的實例可以實施某些動作。為了任何其他目的而定義的接口是不恰當(dāng)?shù)摹?/p>
? ? ? 有一種接口被稱為常量接口(constant interface),這種接口沒有包含任何方法立帖,它只包含靜態(tài)的final域眼溶,每個域都導(dǎo)出一個常量。下面是一個例子
public interface PhysicalConstants {
? ?static final double AVOGADROS_NUMBER ?= 6.23156412e23; //阿伏伽德羅數(shù)
? ?static final double BOLTZMANN_CONSTANT ?= 1.12588456e-23; //玻爾茲曼常數(shù)
? ?static final double ELECTRON_MASS = 9.10938188e-31; //電子質(zhì)量
}
? ? ? 常量接口模式是對接口的不良使用晓勇。類在內(nèi)部使用某些常量堂飞,純粹是實現(xiàn)細(xì)節(jié),實現(xiàn)常量接口绑咱,會導(dǎo)致把這樣的實現(xiàn)細(xì)節(jié)泄露到該類的導(dǎo)出API中绰筛,因為接口中所有的域及方法都是public的。類實現(xiàn)常量接口描融,代表了一種承諾:如果在將來的發(fā)行版本中铝噩,這個類被修改了,它不再需要使用這些常量了窿克,依然必須實現(xiàn)這個接口骏庸,以確保二進制兼容性。如果非final類實現(xiàn)了常量接口年叮,它的所有子類的命名空間都受到了污染具被。
那既然不適合存在全部都是導(dǎo)出常量的常量接口,那么如果需要導(dǎo)出常量谋右,它們應(yīng)該放在哪里呢硬猫?
1.如果這些常量與某些現(xiàn)有的類或者接口緊密相關(guān),就應(yīng)該把這些常量添加到這個類或者接口中(如Integer和Double)改执,注意啸蜜,這里說添加到接口中并不是指的常量接口。在Java平臺類庫中所有的數(shù)值包裝類都導(dǎo)出MIN_VALUE和MAX_VALUE常量辈挂。如果這些常量最好被看作是枚舉類型成員衬横,那就應(yīng)該用枚舉類型來導(dǎo)出终蒂。
如:int類型的取值范圍是多少?
這就應(yīng)該去查 Integer -- Integer.MAX_VALUE;
public enum PhysicalConstants {
? ? ? ?AVOGADROS_NUMBER(6.23156412e23),BOLTZMANN_CONSTANT(1.12588456e-23),ELECTRON_MASS(9.10938188e-31);
? ? ? ?private final Double constant;
? ? ? ?PhysicalConstants(Double number) {
? ? ? ? ? ? ?thie.constant = number;
? ? ? ?}
? ? ? ?public Double constant() {
? ? ? ? ? ? ?return constant;
? ? ? ?}
}
2.應(yīng)該使用不可實例化的工具類來導(dǎo)出這些常量矮锈。
public class PhysicalConstants {
? ?private PhysicalConstants() {}
? ?public static final double AVOGADROS_NUMBER = 6.23156412e23;
? ?public static final double BOLTZMANN_CONSTANT = 1.12588456e-23;
? ?...
}
工具類通常要求客戶端要用類名來修飾這些常量名。例如PhysicalConstants.AVOGADROS_NUMBER瀑凝。如果大量利用工具類導(dǎo)出的常量,那么可以通過靜態(tài)導(dǎo)入(static import)機制來避免用類名來修飾常量名粤咪。靜態(tài)導(dǎo)入的作用是把PhysicalConstants類中的AVOGADROS_NUMBER 渴杆、BOLTZMANN_CONSTANT 等常量引入到本類中,這會使程序更簡單脉顿,更容易閱讀,只要看到AVOGADROS_NUMBER就知道這是阿伏伽德羅常數(shù)敢辩,不用每次都要把類名寫全了戚长。但是,濫用靜態(tài)導(dǎo)入會使程序更難閱讀柑司,更難維護迫肖。
// Use of static import to avoid qualifying constants ?
import static effectivejava.PhysicalConstants.*; ?
?
public class Test { ?
? ?double atoms(double mols) { ?
? ? ? ?return AVOGADROS_NUMBER?* mols; ?
? ?} ?
? ?... ?
? ?// Many more uses of PhysicalConstants justify static import ?
}
PS:在Java程序中蟆湖,是不允許定義獨立的函數(shù)和常量(準(zhǔn)確的說诬垂,只是被final修飾充蓝、只能賦值一次的變量)的。即使從它們本身的功能來看悠垛,完全不需要依附于什么東西,也要找個類或接口作為掛靠單位才行(在類里可以掛靠各種成員,而接口里則只能掛靠常量)。
? ? ? ?掛靠的方法近迁,是把它們加上static修飾符鉴竭,定義為這個類或接口的靜態(tài)成員瑰步。這方面的典型例子是java.lang.Math類——包含了大量的sin责静、cos這樣的“函數(shù)”和PI、E這樣的“常量”睦焕。
? ? ? ?傳統(tǒng)上藐握,在訪問這些掛靠了的函數(shù)靴拱、變量和常量的時候,需要在前面加上它們掛靠單位的名稱猾普。如果只是偶爾訪問這些東西一下袜炕,這樣的寫法可以工作得很好;但是如果要頻繁訪問這些成員的話初家,這樣的寫法就顯得比較羅嗦了偎窘。
簡而言之,接口應(yīng)該只用來定義類型溜在,它不應(yīng)該被用來導(dǎo)出常量陌知。