该主题大部分都说明了 - 静态方法无法在接口中声明的原因是什么?
public interface ITest { public static String test(); }
上面的代码给出了以下错误(至少在Eclipse中):"接口方法ITest.test()的非法修饰符;只允许使用public和abstract".
这里有一些问题在起作用.第一个是在不定义静态方法的情况下声明静态方法的问题.这是两者之间的区别
public interface Foo { public static int bar(); }
和
public interface Foo { public static int bar() { ... } }
由于Espo提到的原因,第一个是不可能的:你不知道哪个实现类是正确的定义.
Java 可以允许后者; 事实上,从Java 8开始,它确实如此!
您不能在接口中使用静态方法的原因在于Java解析静态引用的方式.在尝试执行静态方法时,Java不会费心寻找类的实例.这是因为静态方法不依赖于实例,因此可以直接从类文件中执行.鉴于接口中的所有方法都是抽象的,VM必须寻找接口的特定实现,以便找到静态方法背后的代码,以便可以执行它.这与静态方法解析的工作原理相矛盾,并会在语言中引入不一致.
我将以一个例子回答你的问题.假设我们有一个带有静态方法add的Math类.您可以这样调用此方法:
Math.add(2, 3);
如果Math是接口而不是类,则它不能具有任何已定义的函数.因此,说Math.add(2,3)之类的东西毫无意义.
原因在于设计原则,即java不允许多重继承.以下示例可以说明多重继承的问题:
public class A { public method x() {...} } public class B { public method x() {...} } public class C extends A, B { ... }
现在如果你调用Cx()会发生什么?会执行Ax()还是Bx()?每个具有多重继承的语言都必须解决这个问题.
接口允许在Java中进行某种受限制的多重继承.为避免上述问题,不允许使用方法.如果我们看一下接口和静态方法的相同问题:
public interface A { public static method x() {...} } public interface B { public static method x() {...} } public class C implements A, B { ... }
同样的问题,如果你调用Cx()会发生什么?
静态方法不是实例方法.没有实例上下文,因此从界面实现它没有多大意义.
现在,Java8允许我们在接口中定义甚至静态方法.
interface X { static void foo() { System.out.println("foo"); } } class Y implements X { //... } public class Z { public static void main(String[] args) { X.foo(); // Y.foo(); // won't compile because foo() is a Static Method of X and not Y } }
注意:如果我们没有明确地使用关键字default/static来使它们成为默认方法和静态方法,则默认情况下,接口中的方法仍然是公共抽象.