今天接口中的字段有一个很好的用例吗?

Mic*_*ckJ 4 java interface ambiguity

Java允许接口中的字段.这在java 5之前有一些用处.今天它们有什么好的用例吗?

有人可以给我一些很好的用例,其中一个人会在接口中使用字段而不是其他许多方法来满足相同的设计要求吗?

实际上,界面允许在某些情况下出现歧义和混淆.以此为例.以下代码:

请注意,我承认之前已经讨论过歧义问题并得到了回答,但这不是我的问题.我的问题在上面以粗体显示.这只是界面中字段的一个潜在副作用的说明.

public class Sample implements Foo,Bar{

    public void print() {
        System.out.println("Hello"+name);//field name is ambiguous
    }

    public static void main(String[] args) {
        Sample mySample = new Sample();
        mySample.print();
    }

}

public interface Foo {
    String name = "foo";
}

public interface Bar{
    String name = "bar";
}
Run Code Online (Sandbox Code Playgroud)

ass*_*ias 6

接口用于定义合同,而常量是实现细节.如果有许多实现将共享一个常量是有意义的,您可以在一个抽象类中定义它,该类将用作层次结构的基类.如果只有一个类真的与常量相关联,那么你应该在那里声明它.

如果您只想将一定数量的常量组合在一起,可以在最终类中定义它们:

final class Constants { //non extendable
    public static final double PI = 3.14d;
    public static final double E = 2.13d; //Can't remember the real value!

    private Constants() {} //non instantiable
}
Run Code Online (Sandbox Code Playgroud)

当它们是枚举时(例如颜色),您也可以在枚举中声明它们.

在Effective Java Item#19"仅使用接口来定义类型"中有更多相关内容,其结论为:

总之,接口应仅用于定义类型.它们不应该用于导出常量.

最重要的是,总是有一种更好的方法来定义常量而不是界面.

  • @MickJ Joshua Bloch在第19项中总结:"*总之,接口应仅用于定义类型.它们不应用于导出常量.*".我认为他有资格作为权威来源. (3认同)

Cos*_*lis 5

如果有人设法给你一些好的情况,其中一个人会在接口中使用字段而不是许多其他方法来满足相同的设计要求,它会自动证明在接口中使用常量是合理的.

实际上,这是我们过去在Java的第一个版本中所做的事情.从那以后,接口中的常量被放弃了,转而支持静态导入,静态导入也不是完美的常量类.

如Java文档中所述:

"那么什么时候应该使用静态导入?非常谨慎!只有在你想要声明常量的本地副本或滥用继承(Constant Interface Antipattern)时才使用它.换句话说,当你需要频繁使用它时从一个或两个类访问静态成员."

根据Joshua Bloch(Bloch,Joshua,Effective Java,第2版,第98页),使用常量接口模式的缺点如WikiPedia中所示:

  1. 它使用可能没有用的只读变量来污染类命名空间.
  2. 与实现常量接口的编译时战术实用程序相反,偶然的运行时工件几乎没有实际用途(参见标记接口,它们也没有方法,但在运行时很有用).
  3. 如果在将来的版本中需要二进制代码兼容性,那么常量接口必须永远保持一个接口(它不能转换为类),即使它没有被用作传统意义上的接口.
  4. 如果没有解析常量来源的IDE,将其追溯到包含类或接口可能非常耗时.
  5. 接口的变量(表示实例)在语法上不比接口名本身有用(因为它没有方法).

  • 我不想这么绝对地表达它,但我认为接口应该处理类的行为而不是数据. (2认同)