1. 程式人生 > >第19條:接口只用於定義類型

第19條:接口只用於定義類型

例如 空間 9.1 utility cal 通過 integer 1.5 ann

當類實現接口時,接口就充可以引用這個類的實例的類型。因此,類實現了接口,就表明客戶端可以對這個類的實例實施某些動作。為了任何其他目的而定義接口是不恰當的。

有一種接口被稱為常量接口(constant interface),它不滿足上面的條件。這種接口沒有包含任何方法,它只包含靜態的final域,每個域都導出一個常量。使用這些常量的類實現這個接口,以避免用類名來修飾常量名。下面是一個例子:

1 public interface PhysicalConstants {
2     static final double AVOGADROS_NUMBER = 6.02214199e23;
3 static final double BOLTZMANN_CONSTANT = 1.3806503e-23; 4 static final double ELECTRON_MASS = 9.10938188e-31; 5 }

常量接口模式是對接口的不良使用。類在內部使用某些常量,這純粹是實現細節。實現常量接口,會導致把這樣的實現細節泄露到該類的導出API中。類實現常量接口,這對於這個類的用戶來講並沒有什麽價值。實際上,這樣做反而會使他們更加糊塗。更糟糕的是,它代表了一種承諾:如果再將來的發行版本中,這個類被修改了,它不在需要使用這些常量了,它依然必須實現這個接口,以確保二進制兼容性。如果非final類實現了常量接口,它的所有子類的命名空間也會被接口中的常量所“汙染”。

如果要導出常量,可以有幾種合理的選擇方案。如果這些常量與某個現有的類或者接口緊密相關,就應該把這些常量添加到這個類或者接口中。例如,在Java平臺類庫中所有的數值包裝類,如Integer或Double,都導出了MIN_VALUE和MAX_VALUE常量。如果這些常量最好被看作枚舉類型的成員,就應該用枚舉類型(enum type)來導出這些常量。否則,應該使用不可實例化的工具類(utility class)來導出這些常量。下面的例子是前面的PhysicalConstants例子的工具類翻版:

1 public class PhysicalConstants {
2     private
PhysicalConstant() {}; 3 public static final double AVOGADROS_NUMBER = 6.02214199e23; 4 public static final double BOLTZMANN_CONSTANT = 1.3806503e-23; 5 public static final double ELECTRON_MASS = 9.10938188e-31; 6 }

工具類通常要求客戶端要使用類名來修飾這些常量名,例如PhysicalConstants.AVOGADROS_NUMBER。如果大量利用工具類導出的常量,可以通過利用靜態導入(static import)機制,避免用類名來修飾常量名,不過,靜態導入機制是在Java發行版本1.5中才引入的。

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

第19條:接口只用於定義類型