Home > Net >  Static member method to Instance member method redeclaration allowed for Interface-Class but not for
Static member method to Instance member method redeclaration allowed for Interface-Class but not for

Time:11-05

Consider the following snippet:

interface Super{
    public static void doIt(){}
}
class Sub implements Super{
    public void doIt(){}
}
  • Here I have declared a static member method and it is being redeclared as the instance method in the child class.
  • This is allowed by the compiler - but when I do the same with the superclass and subclass types - this gives compilation error:
class Super{
    public static void doIt(){}
}
class Sub extends Super{
    public void doIt(){}
}
  • What is the rationale behind the same? - ideally the way to access the subclass is essentially the same - then why this restriction?

CodePudding user response:

The reason for this is that Java allows invoking static methods in a non-static manner. Consider this example:

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

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

This will produce a compiler warning (The static method sayHello() from the type MyClass should be accessed in a static way), but it will compile and invoke the static method correctly at runtime.

That's why the following code will not compile because of an ambiguity (Duplicate method test() in type MyClass):

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

    public void test() {
    }
}

The reason for the compile error is, that if you write the following, the compiler cannot know which method to invoke, because it allows to call static methods in a non-static manner:

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

    public void test() {
    }

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

For the same reason it is not possible to have the static test() method in the parent class - the same rules apply. It is possible in Java to call static methods of super classes with or without qualification:

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

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

OR

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

where the invocation of this.test() will produce a warning, but will work at runtime.

For static methods in interfaces, the above example will not work, because the compiler forces you to call the static method of the interface in a qualified manner. The following will not work (The method interfaceStatic() is undefined for the type Sub):

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

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

In order to call interfaceStatic() the invocation has to be qualified like this:

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

That's the difference between defining the static method in an interface and defining it in the super class: The way of invocation. If you implement multiple interfaces which all have a static method with the same signature, the compiler cannot know which one to call.

This is the reason why it is allowed to define a static method with the same signature in an implemented interface, but not in the parent classes.

  • Related