为什么接口variables默认静态和最终?

为什么在Java中默认的接口variables是静态的和最终的?

从Philip Shaw的Java界面deviseFAQ:

接口variables是静态的,因为Java接口不能自己实例化; variables的值必须在没有实例存在的静态上下文中分配。 最终修饰符确保赋给接口variables的值是一个真正的常量,不能被程序代码重新赋值。

资源

由于接口没有直接的对象,访问它们的唯一方法是使用类/接口,因此如果接口variables存在,它应该是静态的,否则根本不能访问到外部世界。 既然它是静态的,它只能保存一个值,任何实现它的类都可以改变它,所以它会一团糟。

因此,如果有一个接口variables,它将是隐式静态的,最终的,显然是公共的!

public :所有类的可访问性,就像界面中的方法一样

静态的 :因为接口不能有对象,所以可以使用interfaceName.variableName来引用它,或者直接在实现它的类中使用variableName。

最后 :使他们常量。 如果2个类实现相同的接口,并且你给他们两个权限来改变值,那么var的当前值就会发生冲突,这就是为什么只允许一次初始化的原因。

所有这些修饰符都是隐式的接口,你不需要指定它们中的任何一个。

因为其他任何东西都是实现的一部分,并且接口不能包含任何实现。

静态 – 因为接口不能有任何实例。 和最后的 – 因为我们不需要改变它。

这不是一个哲学的答案,但更多的是一个实际的答案 )。 对static修饰符的要求是显而易见的,已经被其他人回答了。 基本上,由于接口不能实例化,访问其字段的唯一方法是使它们成为一个类字段 – static

interface字段自动成为final (常量)的原因是为了防止不同的实现意外地改变接口variables的值,这会不经意地影响其他实现的行为。 想象一下interface属性没有被Java明确地定义为final的场景:

 public interface Actionable { public static boolean isActionable = false; public void performAction(); } public NuclearAction implements Actionable { public void performAction() { // Code that depends on isActionable variable if (isActionable) { // Launch nuclear weapon!!! } } } 

现在,想想如果另一个实现了Actionable类改变了接口variables的状态会发生什么:

 public CleanAction implements Actionable { public void performAction() { // Code that can alter isActionable state since it is not constant isActionable = true; } } 

如果这些类是通过类加载器在单个JVM中加载的,那么在执行CleanAction (在同一个线程或其他types)之后调用performAction()时,可能会受到另一个类CleanAction影响,在这种情况下可能是灾难性的(语义上就是这样)。

由于我们不知道interface每个实现如何使用这些variables,因此它们必须隐含地是final

 public interface A{ int x=65; } public interface B{ int x=66; } public class D implements A,B { public static void main(String[] a){ System.out.println(x); // which x? } } 

这是解决scheme。

 System.out.println(Ax); // done 

我认为这是接口variables为静态的原因之一。

不要在Interface中声明variables。

Java不允许在接口中使用抽象variables和/或构造函数定义。 解决scheme:简单地在你的接口和你的实现之间挂一个抽象类,它只扩展抽象类,如下所示:

  public interface IMyClass { void methodA(); String methodB(); Integer methodC(); } public abstract class myAbstractClass implements IMyClass { protected String varA, varB; //Constructor myAbstractClass(String varA, String varB) { this.varA = varA; this.varB = VarB; } //Implement (some) interface methods here or leave them for the concrete class protected void methodA() { //Do something } //Add additional methods here which must be implemented in the concrete class protected abstract Long methodD(); //Write some completely new methods which can be used by all subclasses protected Float methodE() { return 42.0; } } public class myConcreteClass extends myAbstractClass { //Constructor must now be implemented! myClass(String varA, String varB) { super(varA, varB); } //All non-private variables from the abstract class are available here //All methods not implemented in the abstract class must be implemented here } 

你也可以使用一个没有任何接口的抽象类如果你确定你不想和其他接口一起实现它。 请注意,你不能创build一个抽象类的实例,你必须首先扩展它。

(“protected”关键字意味着只有扩展类才能访问这些方法和variables。)

SPYRO

界面是双方之间的契约,不变,刻在石头上,因此是最终的。 请参阅按合同devise 。

Java ,接口不允许声明任何实例variables。 使用在接口中声明的variables作为实例variables将返回编译时错误。

你可以使用static final来声明一个常量variables,它与实例variables不同。

接口可以通过任何类来实现,如果这个接口的值被其中一个实现类改变了,那么其他的实现类就会被误导。 接口基本上是将两个相互联系但是不同的实体组合在一起的引用。因此,接口中的声明variables将隐含地是最终的,也是静态的,因为接口不能被实例化。

想想一个你定义了接口的Web应用程序,其他类实现它。 由于你不能创build一个接口的实例来访问variables,你需要一个static关键字。 由于它的静态值的任何变化将反映到其他已经实现它的实例。 所以为了防止它,我们将它们定义为final。

刚刚在Eclipse中尝试过,接口中的variables默认是最终的,所以你不能改变它。 与父类相比,variables绝对是可以改变的。 为什么? 从我的angular度来说,class里的变数是一个会被孩子遗传下来的属性,孩子们可以根据自己的实际需要来改变它。 相反,界面只定义行为,而不是属性。 在接口中放入variables的唯一原因是将它们用作与该接口相关的常量。 虽然,根据以下摘录,这不是一个好的做法:

“在接口中放置常量是Java早期的stream行技术,但现在很多人认为它是一个令人厌恶的接口使用,因为接口应该处理对象提供的服务,而不是数据,而且使用的常量一个类通常是一个实现细节,但是将它们放在一个接口中会促使它们进入该类的公共API。

我也试过把静态或没有任何差别。 代码如下:

 public interface Addable { static int count = 6; public int add(int i); } public class Impl implements Addable { @Override public int add(int i) { return i+count; } } public class Test { public static void main(String... args) { Impl impl = new Impl(); System.out.println(impl.add(4)); } } 

我认为这是因为接口不能实例化,所以所有的variables声明为static 。 使用final关键字表示它没有正文。