如果超类和子类在其表中都有相同方法签名的条目,则首先遇到子类的版本,并且永远不使用超类的版本 - 这是“覆盖”。
现在,假设我们跳过对象实例,并从一个子类开始。 分辨率可以如上所述进行,为您提供一种“可覆盖的”静态方法。 然而,解决方案都可以在编译时发生,因为编译器是从已知类开始的,而不是等到运行时查询其类的未指定类型的对象。 “覆盖”静态方法没有意义,因为总是可以指定包含所需版本的类。
构造函数“接口”
这里有一些材料可以解决最近编辑的问题。
听起来你想要为Foo的每个实现有效地强制使用类似构造函数的方法。忘记尝试用接口强制执行一分钟,并假装你有一些符合这个要求的类。 你会怎么用?
class Foo implements IXMLizable{ public static Foo newInstanceFromXML(Element e) { ... } } Foo obj = Foo.newInstanceFromXML(e);
由于在“构造”新对象时必须明确命名具体类型Foo,因此编译器可以验证它确实具有必要的工厂方法。 如果没有,那么呢? 如果我可以实现缺少“构造函数”的IXMLizable,并创建一个实例并将其传递给您的代码,那么它是一个带有所有必要接口的IXMLizable。
构造是实现的一部分,而不是接口。 任何与接口一起成功运行的代码都不关心构造函数。 任何关心构造函数的代码都需要知道具体类型,并且可以忽略该接口。
43 votes
这已经被问到并回答了
要复制我的答案:
在接口中声明静态方法永远不会有意义。 它们不能通过正常调用MyInterface.staticMethod()执行。 如果通过指定实现类MyImplementor.staticMethod()来调用它们,那么您必须知道实际的类,因此接口是否包含它是无关紧要的。
更重要的是,静态方法永远不会被覆盖,如果你尝试这样做:
MyInterface var = new MyImplementingClass(); var.staticMethod();
静态规则说必须执行在声明的var类型中定义的方法。 由于这是一个界面,这是不可能的。
您无法执行“result = MyInterface.staticMethod()”的原因是它必须执行MyInterface中定义的方法的版本。 但MyInterface中不能定义版本,因为它是一个接口。 根据定义,它没有代码。
虽然你可以说这相当于“因为Java就是这样做的”,但实际上这个决定是其他设计决策的逻辑结果,也是出于非常好的理由。
34 votes
通常这是使用工厂模式完成的
public interface IXMLizableFactory{ public T newInstanceFromXML(Element e); } public interface IXMLizable { public Element toXMLElement(); }
30 votes
随着Java 8的出现,现在可以在接口中编写默认和静态方法。docs.oracle/staticMethod
例如:
public interface Arithmetic { public int add(int a, int b); public static int multiply(int a, int b) { return a * b; } }public class ArithmaticImplementation implements Arithmetic { @Override public int add(int a, int b) { return a + b; } public static void main(String[] args) { int result = Arithmetic.multiply(2, 3); System.out.println(result); } }
结果:6
提示:调用静态接口方法不需要由任何类实现。 当然,这是因为超类中静态方法的相同规则适用于接口上的静态方法。
19 votes
因为静态方法不能在子类中重写,因此它们不能是抽象的。 接口中的所有方法事实上都是抽象的。
9 votes
为什么我不能在Java接口中定义静态方法?
实际上你可以在Java 8中。
根据Java doc:
静态方法是与其中的类相关联的方法 它被定义而不是任何对象。 班级的每个实例 分享其静态方法
在Java 8中,接口可以具有默认方法和静态方法。 这使我们更容易在库中组织辅助方法。 我们可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。

默认方法示例:

list.sort(ordering);
代替
Collections.sort(list, ordering);

静态方法的示例(来自doc本身):

public interface TimeClient { // ... static public ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead."); return ZoneId.systemDefault(); } } default public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
6 votes
首先,所有语言决策都是语言创建者做出的决定。 在软件工程或语言定义或编译/解释器编写领域,没有任何内容表明静态方法不能成为接口的一部分。 我为他们创建了几种语言和编写的编译器 - 它们只是坐下来定义有意义的语义。 我认为接口中静态方法的语义非常清晰 - 即使编译器必须将方法的解析推迟到运行时。
其次,我们一直使用静态方法有一个有效的理由,有一个包含静态方法的接口模式 - 我不能代表任何人,但我定期使用静态方法。
最可能的正确答案是,在定义语言时,没有感觉到需要接口中的静态方法。 多年来Java已经发展了很多,这个项目显然已经获得了一些兴趣。 对Java 7进行了研究表明它已经上升到可能导致语言变化的兴趣水平。 当我不再需要实例化一个对象时,我会很高兴我可以调用我的非静态getter方法来访问子类实例中的静态变量...
5 votes
接口与多态性有关,多态性本质上与对象实例有关,而与类无关。 因此,静态在接口的上下文中没有意义。
5 votes
“是否有一个特殊原因导致静态方法无法被覆盖”。
让我通过填写定义为你重新提出这个问题。
“在编译时解析的方法是否有特殊原因无法在运行时解析。”
或者,更完整地说,如果我想调用没有实例的方法,但是知道类,我怎样才能根据我没有的实例来解析它。
4 votes
静态方法不像实例方法那样虚拟,所以我认为Java设计者认为他们不希望它们在接口中。
但是您可以将包含静态方法的类放在接口中。 你可以试试!
public interface Test { static class Inner { public static Object get() { return 0; } } }
3 votes