第19条:接口只用于定义类型
2014-07-06 10:33
197 查看
术语:
常量接口(constant interface):这种接口不包含任何方法,它只包含静态的final域,每个域都导出一个常量。
当类实现接口时,接口就充当可以引用这个类的实例类型。因此,类实现了接口,就表明客户端对这个类的实例可以实施某些动作。为了任何其他目的而定义的接口是不恰当的。
常量接口是对接口的一种不良使用。类在内部使用某些常量,纯粹是实现细节,实现常量接口,会导致把这样的实现细节泄露到该类的导出API中,因为接口中所有的域都是及方法public的。类实现常量接口,这对于这个类的用户来讲并没有实际的价值。实际上,这样做返回会让他们感到更糊涂,这还代表了一种承诺:如果在将来的发行版本中,这个类被修改了,它不再需要使用这些常量了,依然必须实现这个接口,以确保二进制兼容性。如果非final类实现了常量接口,它的所有子类的命名空间都受到了污染。Java平台类库中存在几个常量接口,如java.io.ObjectStreamConstants,这些接口都是反面典型,不值得效仿。
那既然不适合存在全部都是导出常量的常量接口,那么如果需要导出常量,它们应该放在哪里呢?如果这些常量与某些现有的类或者接口紧密相关,就应该把这些常量添加到这个类或者接口中,注意,这里说添加到接口中并不是指的常量接口。在Java平台类库中所有的数值包装类都导出MIN_VALUE和MAX_VALUE常量。如果这些常量最好被看作是枚举类型成员,那就应该用枚举类型来导出。否则,应该使用不可实例化的工具类来导出这些常量。
常量接口(constant interface):这种接口不包含任何方法,它只包含静态的final域,每个域都导出一个常量。
当类实现接口时,接口就充当可以引用这个类的实例类型。因此,类实现了接口,就表明客户端对这个类的实例可以实施某些动作。为了任何其他目的而定义的接口是不恰当的。
常量接口是对接口的一种不良使用。类在内部使用某些常量,纯粹是实现细节,实现常量接口,会导致把这样的实现细节泄露到该类的导出API中,因为接口中所有的域都是及方法public的。类实现常量接口,这对于这个类的用户来讲并没有实际的价值。实际上,这样做返回会让他们感到更糊涂,这还代表了一种承诺:如果在将来的发行版本中,这个类被修改了,它不再需要使用这些常量了,依然必须实现这个接口,以确保二进制兼容性。如果非final类实现了常量接口,它的所有子类的命名空间都受到了污染。Java平台类库中存在几个常量接口,如java.io.ObjectStreamConstants,这些接口都是反面典型,不值得效仿。
那既然不适合存在全部都是导出常量的常量接口,那么如果需要导出常量,它们应该放在哪里呢?如果这些常量与某些现有的类或者接口紧密相关,就应该把这些常量添加到这个类或者接口中,注意,这里说添加到接口中并不是指的常量接口。在Java平台类库中所有的数值包装类都导出MIN_VALUE和MAX_VALUE常量。如果这些常量最好被看作是枚举类型成员,那就应该用枚举类型来导出。否则,应该使用不可实例化的工具类来导出这些常量。
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。如果大量利用工具类导出的常量,那么可以通过静态导入(static import)机制来避免用类名来修饰常量名。
// 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 }总之,接口应该只被用来定义类开,它们不应该用来导出常量。
相关文章推荐
- 第19条:接口只用于定义类型
- 第19条:接口只用于定义类型
- 《Effective java》读书记录-第19条-接口只用于定义类型
- 第19条:接口只用于定义类型
- 为什么 接口只用于定义类型,不应该使用常量接口 ?
- 用于创建实现 System.ComponentModel.INotifyPropertyChanged 接口的动态类型,并添加各个 public 属性的定义
- 接口只用于定义类型,不应该使用常量接口
- 接口只用于定义类型
- 第十九条:接口只用于定义类型
- Effective Java - 类和接口 - 接口只用于定义类型
- EffectiveJava(19)导出常量的几种方式 - - 接口只用于定义类型
- 接口只用于定义类型。
- (19):接口只用于定义类型
- effective java(19) 之接口只用于定义类型
- 接口只用于定义类型
- 接口只用于定义类型
- Effective java 第 19 条: 接口只用于定义类型
- Java学习笔记14:接口只用于定义类型
- 接口只用于定义类型。
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义