第19條 接口只用于定義類型

當類實現(xiàn)接口時,接口就充當可以引用這個類的實例的類型。因此,類實現(xiàn)了接口,就表明客戶端對這個類的實例可以實施某些動作。為了任何其他目的而定義的接口是不恰當?shù)摹?/p>

? ? ? 有一種接口被稱為常量接口(constant interface),這種接口沒有包含任何方法,它只包含靜態(tài)的final域,每個域都導出一個常量。下面是一個例子

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)細節(jié),實現(xiàn)常量接口,會導致把這樣的實現(xiàn)細節(jié)泄露到該類的導出API中,因為接口中所有的域及方法都是public的。類實現(xiàn)常量接口,代表了一種承諾:如果在將來的發(fā)行版本中,這個類被修改了,它不再需要使用這些常量了,依然必須實現(xiàn)這個接口,以確保二進制兼容性。如果非final類實現(xiàn)了常量接口,它的所有子類的命名空間都受到了污染。

那既然不適合存在全部都是導出常量的常量接口,那么如果需要導出常量,它們應該放在哪里呢?

1.如果這些常量與某些現(xiàn)有的類或者接口緊密相關,就應該把這些常量添加到這個類或者接口中(如Integer和Double),注意,這里說添加到接口中并不是指的常量接口。在Java平臺類庫中所有的數(shù)值包裝類都導出MIN_VALUE和MAX_VALUE常量。如果這些常量最好被看作是枚舉類型成員,那就應該用枚舉類型來導出。

如:int類型的取值范圍是多少?

這就應該去查 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.應該使用不可實例化的工具類來導出這些常量。

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。如果大量利用工具類導出的常量,那么可以通過靜態(tài)導入(static import)機制來避免用類名來修飾常量名。靜態(tài)導入的作用是把PhysicalConstants類中的AVOGADROS_NUMBER 、BOLTZMANN_CONSTANT 等常量引入到本類中,這會使程序更簡單,更容易閱讀,只要看到AVOGADROS_NUMBER就知道這是阿伏伽德羅常數(shù),不用每次都要把類名寫全了。但是,濫用靜態(tài)導入會使程序更難閱讀,更難維護。

// 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ù)和常量(準確的說,只是被final修飾、只能賦值一次的變量)的。即使從它們本身的功能來看,完全不需要依附于什么東西,也要找個類或接口作為掛靠單位才行(在類里可以掛靠各種成員,而接口里則只能掛靠常量)。

? ? ? ?掛靠的方法,是把它們加上static修飾符,定義為這個類或接口的靜態(tài)成員。這方面的典型例子是java.lang.Math類——包含了大量的sin、cos這樣的“函數(shù)”和PI、E這樣的“常量”。

? ? ? ?傳統(tǒng)上,在訪問這些掛靠了的函數(shù)、變量和常量的時候,需要在前面加上它們掛靠單位的名稱。如果只是偶爾訪問這些東西一下,這樣的寫法可以工作得很好;但是如果要頻繁訪問這些成員的話,這樣的寫法就顯得比較羅嗦了。

簡而言之,接口應該只用來定義類型,它不應該被用來導出常量。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 當類實現(xiàn)接口時,接口就充當可以引用這個類的實例的類型(type)。因此類實現(xiàn)了接口,就表明客戶端可以對這個類的實例...
    NekoJiang閱讀 690評論 0 0
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 枚舉類型是指由一組固定的常量組成合法值的類型,例如一年中的季節(jié),太陽系中的行星或者一副牌中的花色。在編程語言...
    小小輝_710a閱讀 1,456評論 0 0
  • 對象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構造函數(shù)創(chuàng)建對象:僅僅是創(chuàng)建對象的方法,并非Fa...
    孫小磊閱讀 2,021評論 0 3
  • 雖然用了“御用白衣天使”的專用配方,我今天還是在床上度過大半天,頭還有點暈痛感。 今天是戰(zhàn)友聚會日,看到自己的狀態(tài)...
    D066有情人尋找紅辣椒佛山閱讀 310評論 2 3