Interface-Class允许静态成员方法到实例成员方法重新声明,但Class-Class或Interface-Interface不允许

Static member method to Instance member method redeclaration allowed for Interface-Class but not for Class-Class or Interface-Interface

考虑以下片段:

interface Super{
    public static void doIt(){}
}
class Sub implements Super{
    public void doIt(){}
}
class Super{
    public static void doIt(){}
}
class Sub extends Super{
    public void doIt(){}
}

原因是 Java 允许以非静态方式调用 static 方法。考虑这个例子:

public class MyClass {
    public static void sayHello() {
    }

    public void test() {
        this.sayHello();
    }
}

这会产生一个编译器警告(类型MyClass中的静态方法sayHello()应该以静态方式访问),但是它会在运行时正确编译和调用静态方法。

这就是以下代码因歧义而无法编译的原因(类型 MyClass 中的重复方法 test()):

public class MyClass {
    public static void test() {
    }

    public void test() {
    }
}

编译错误的原因是,如果您编写以下内容,编译器无法知道调用哪个方法,因为它允许以非静态方式调用 static 方法:

public class MyClass {
    public static void test() {
    }

    public void test() {
    }

    public void execute() {
        this.test();
    }
}

出于同样的原因,不可能在父 class 中使用 static test() 方法 - 同样的规则适用。在 Java 中调用超级 class 的 static 方法是可能的,有或没有资格:

public class Super {
    public static void test() {
    }
}

public class Sub extends Super {
    public void execute() {
        this.test();
    }
}

public class Sub {
    public void execute() {
        test();
    }
}

调用 this.test() 会产生警告,但会在运行时起作用。

对于接口中的static方法,上面的例子是行不通的,因为编译器强制你以合格的方式调用接口的static方法(编辑:因为它们不是被继承)。以下将 not 工作(方法 interfaceStatic() 未定义类型 Sub):

public interface Interface {
    public static void interfaceStatic() {  
    }
}

public class Sub implements Interface {
    public void test() {
        interfaceStatic();
    }
}

为了调用 interfaceStatic(),调用必须像这样限定:

public class Sub implements Interface {
    public void test() {
        Interface.interfaceStatic();
    }
}

这就是在接口中定义static方法和在superclass中定义方法的区别:调用方式。如果您实现多个接口,这些接口都具有具有相同签名的 static 方法,编译器将无法知道调用哪一个。

这就是为什么允许在实现的接口中定义具有相同签名的 static 方法,但不能在父 classes 中定义方法的原因。