规范声明接口旨在定义一个类可以做什么的契约,并包含一组实现所需的方法。但同时,接口可能有常量。
Java 出于什么目的允许使用它?
接口中常量的存在意义何在?如何在其中使用它们?据我了解,它们只能作为方法的论据。但我看不出有什么意义,因为接口没有说明类将如何实现其方法。
常量也是接口的一部分。设计中使用常量值来避免幻数,即对实现具有一定意义但似乎突然冒出来的数字。
在许多情况下,数值会影响代码的行为。例如,考虑一个 GUI 按钮的界面。这个按钮的实际绘制方式取决于实现;但是什么样的按钮是构成界面的合同的一部分:它是普通的按钮,有图像,还是复选框?可以使用常量来修改此行为,这些常量通常由 OR'ing 值使用:例如,int buttonType = PUSHBUTTON|IMAGEBUTTON
.
常量可以在接口之外使用。
例如,它们可以被实现接口的类使用。如果跨实现类需要单个定义,这可能很有用。
例如,考虑一个接口,它定义了一些可以在所有子类中一致使用的按位或样式常量。只需要这些的一个定义,并且只需要学习一个集合。
想象一个使用图像或声音等资源的应用程序。您可以为您的资源定义一个通用接口。
interface MyResource {
void load();
void dispose();
// ...
}
您的文件夹结构可能如下所示:
+ Root
|--+ Resources
|--+ Images
|--+ Sounds
|--+ Data
你知道你所有的资源都会在Root/Resources/
. 此信息不仅可以由您的资源共享和了解,还可以由您的其他应用程序组件共享和了解。
考虑到这一点,您的界面现在变为:
interface MyResource {
public static final String RESOURCE_ROOT_PATH = "Root/Resources/";
void load();
void dispose();
// ...
}
您的特定实现(例如图像)可能会根据所有资源的公共路径定义自己的根路径。
class MyImage implements MyResource {
public static final String IMAGE_ROOT_PATH =
MyResource.RESOURCE_ROOT_PATH + "Images/";
...
}
或者,您可以查看类似 的接口javax.swing.SwingConstants
,这些接口用于在实现之间共享特定功能的常量。
但是,话又说回来,对于这种事情,我enum
现在宁愿使用 , 。
在 Java 5 之后(它带来enum
了优于位掩码并且也可以在接口上声明的 s )对我而言此类常量的一种用法是当常量是方法契约的一部分时。
考虑这样的接口:
public interface Element {
Element NONE = new EmptyElement();
/**
* Looks up an element using this element as a root.
* If the lookup fails, returns Element.NONE.
*/
Element findElements(String searchBy);
}
常量是方法契约的一部分,因此我认为应该在接口中。这在 API 编程中很有用,因为您可以为 API 方法提供默认或特殊返回值,供所有人使用和检查。
最常见的情况是防止null
返回值不明确的问题(例如,该HashMap#get()
方法将返回null
丢失的键和null
值),但它不仅仅是空值 - 任何可以返回的特殊值都应该是,我想,在界面上。
让我们用一个例子来解释:
public interface People {
/**
* Gets the population for the given type
*/
public Population getPopulationForType(int populationType);
}
你觉得上面的合同容易理解吗?或者以下不是更好吗?
public interface People {
int BLACK_POPULATION_TYPE = 0;
int ASIAN_POPULATION_TYPE = 1;
int WHITE_POPULATION_TYPE = 2;
/**
* Gets the population for the given type
*/
public Population getPopulationForType(int populationType);
}
你可以有一个 FrenchPeople、AmericanPeople 和 ChinesePeople 实现,但都应该返回所有三种可能类型的人的总体。
接口常量的一种可能用途是确保常量在所有实现类中都是可见的。当然,您可以将所有这些放在一个类中并在这些实现类中使用相同的类,但是在规范级别定义常量要容易得多。
这样想;即使常量没有定义“实现”,它们也存在,以防任何实现需要它们。
它们可用于为方法的返回参数/输入参数赋予符号意义。这已经是预枚举的日子了。