为什么我不能使用实例变量访问接口的静态方法。
public class TestClass {
public static void main(String[] args) {
AWD a = new Car();
a.isRearWheelDrive(); //doesn't compile
}
}
interface AWD {
static boolean isRearWheelDrive() {
return false;
}
}
class Car implements AWD {
}
答案 0 :(得分:6)
您无法通过实例访问接口的静态方法。你必须静态访问它们。这与允许通过实例访问静态方法的类略有不同,但通常标记为代码气味;应静态访问静态方法。
那是因为类的静态方法是由子类继承的,但是接口的静态方法不是。在规范的§8.4.8中说明了这一点:
8.4.8. Inheritance, Overriding, and Hiding
...
类不会从其超接口继承静态方法。
当您查找实例的可访问方法时,界面中的静态方法不在其中。
因此,正如代码现在一样,您需要静态访问该方法:
{0.0=Udisk price: 0.0 capacity: 0, 1.0=Udisk price: 1.0 capacity: 1,
2.0=Udisk price: 2.0 capacity: 2, 3.0=Udisk price: 3.0 capacity: 3,
4.0=Udisk price: 4.0 capacity: 4, 5.0=Udisk price: 5.0 capacity: 5,
6.0=Udisk price: 6.0 capacity: 6, 7.0=Udisk price: 7.0 capacity: 7,
8.0=Udisk price: 8.0 capacity: 8, 9.0=Udisk price: 9.0 capacity: 9} 10
但是,您似乎希望这是一个实例方法,在这种情况下,您可能应该使用返回 false 的默认方法:
AWD.isRearWheelDrive()
但是,即使这看起来有点奇怪。看起来您可能希望默认方法覆盖超级接口中的某些非默认方法。也就是说,你可能想要这样的东西:
interface AWD {
default boolean isRearWheelDrive() {
return false;
}
}
答案 1 :(得分:1)
这在The Java® Language Specification, §15.12.3. Compile-Time Step 3: Is the Chosen Method Appropriate?
中指定如果表单是 ExpressionName
.
[TypeArguments] 标识符或主要 {{1 [TypeArguments] Identifier ,然后编译时声明不能是接口中声明的.
方法,否则会发生编译时错误。
回想起来,通过实例调用static
方法的能力几乎没有用,甚至比static
方法的继承更少。我很安静,很多开发人员认为这是一个设计错误,只是出于兼容性原因才会保留。
对于接口中static
方法的新功能,没有需要重复此错误的兼容性约束,因此,接口中static
方法的规则设计不同。这也是对旧代码兼容性影响最小的解决方案。