简体   繁体   中英

Why language designers allow interface to contain fields?

As per Item 19 in Effective Java, one must use an interface to only represent a type. In this case the interface would contain the methods that form part of the public contract that is exposed by a class (implementing the interface) to the clients

If so, why do interfaces support fields in the first place? Since the fields are implicitly public, static, final, (and hence constants), why did the language designers support having them? If they were unsupported then developers would invariably use utils class (with private constructor) to define these constants. The anti pattern of using constants only interfaces could have been automatically avoided

I am looking at understanding the reasons for supporting constants in the interface. Are they essential as part of the contract with the client?

Thanks

One reason might be constants which are essential to the interface's contract. For instance, consider the following interface:

/**
* Generates a probability distribution on a
* specified interval.
*/
public interface DistributionGenerator{
    /*
    * Gets a probability distribution on the specified
    * interval. The exact distribution is unique to the 
    * implementor of this interface. The distribution will
    * be represented as an array of doubles. The first number
    * in the returned array will be the probability at start
    * The last number will be the probability at end. All numbers
    * in between will be probabilities at evenly spaced 
    * intervals between start and end, with the spacing between values
    * given by the constant INTERVAL
    */
    public double[] getDistribution(double start,double end);

    public static final double INTERVAL = 0.000001;
}

However, as you observed, most of the time you see constants in interfaces it is done to simply expose the constants for their own sake, and this is generally considered bad practice .

Are they essential as part of the contract with the client?

They are if the constant can be given as a parameter to one or more of the interface methods, or if the constant is a documented special return value of one or more of the interface methods.

The use of an interface to hold constants for easy use by a class is an anti-pattern, and there are many articles about that, but it is valid to have constants that are specifically for use by the methods defined in the interface itself.

However, using enum types and the new Java 8 Optional will eliminate most use-cases for such special constants, so they are very rarely seen in real life.


As an example, the InputStream.read() methods all return -1 for "end of the stream". Sure, it is well documented, but wouldn't use of the methods be better self-documented if InputStream had defined a END_OF_STREAM constant for -1 ?

while ((len = inputStream.read(bytes)) != InputStream.END_OF_STREAM) {

// or using a static import:
while ((len = inputStream.read(bytes)) != END_OF_STREAM) {

Ok, well, InputStream is an abstract class, not an interface, though it should have been, so not a perfect example, but it illustrates the point I was trying to make.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM