实现类访问接口的静态成员的一些注意点
今天在看接口的时候发现实现类不能访问父接口的静态方法,经过探查之后发现如果是单实现,那么实现类可以访问父接口的静态变量,但是多实现而且多个接口中的静态变量重名就不能使用实现类进行访问了
public interface DemoA { static String a = "123"; static String test() { return "静态方法test()"; } } class DemoB implements DemoA { public static void main(String[] args) { DemoB demoB = new DemoB(); System.out.println(demoB.a); //实现类的实例可以调用接口中的静态变量 System.out.println(DemoB.a); //实现类可以直接调用接口中的静态变量 // System.out.println(demoB.test()); //实现类的实例不可以调用接口中的静态方法 // System.out.println(DemoB.test()); //实现类不可以直接调用接口的静态方法 } } interface DemoC { static String a = "456"; } class DemoD implements DemoA, DemoC { public static void main(String[] args) { DemoD demoD = new DemoD(); //当实现类实现了两个接口,两个接口有一样的成员变量的时候 //此时实现类和实现类的实例都无法调用接口的静态变量了,因为编译器无法选择 // System.out.println(demoD.a); // System.out.println(DemoD.a); } }
如果是子类和父类的继承关系(单继承),不存在这种情况,使用子类.父类static变量没有问题,子类.父类静态方法也没问题
其实,我觉得不用纠结这个问题:
关于接口的静态变量在JDK1.0就进行了定义,一开始的设计考虑不了太多,我猜关于实现类对象可以直接调用接口静态变量就是那时候定义的。
但是关于接口静态方法在JDK1.8才有了定义,而这时如何调用静态方法和静态变量明确是在类型信息初始化阶段就和类本身绑定在一起,尽量应该使用它们两者所属类或者接口来调用,即接口I的静态方法和变量就应该用I.a和I.test()来调用,其它的方式都不建议。
你所考虑的问题确实是多实现可能导致的,这应该是禁止实现类对象和类本身去调用接口的静态方法的主要原因。
关于为什么可以调用接口静态变量,我猜应该是考虑到兼容性,避免使用老版本JDK的程序崩溃。
所以在访问父接口或者父类的静态成员时,还是使用父接口或者父类名进行访问最稳妥。