3

I'm confused why the following is not allowed:

public interface MyInterface {
  MyInterface getInstance(String name);
}

public class MyImplementation implements MyInterface {
  public MyImplementation(String name) {
  }
  @Override
  public static MyInterface getInstance(String name) { // static is not allowed here
    return new MyImplementation(name)
  }
}

I understand why a method in the interface cannot be static, but why can't the overriding method be?

I want all classes to implement the getInstance(String name) method, but I'm currently limited to only being able to call the method if the object has already been instantiated which kind of defeats the purpose...


*update:* Thanks for the answers, I understand it better now. Basically I shouldn't be trying to make a utility class (or a factory class for that matter) implement an interface (or at least, not in this way)...

KidTempo
  • 910
  • 1
  • 6
  • 22
  • Think about it, how would you call an overriden static method? – biziclop Jul 02 '12 at 15:33
  • 1
    possible duplicate of [Why doesn't Java allow overriding of static methods?](http://stackoverflow.com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods) (or else of [Why can't I declare static methods in an interface?](http://stackoverflow.com/questions/21817/why-cant-i-declare-static-methods-in-an-interface?rq=1)) – Ted Hopp Jul 02 '12 at 15:33
  • 1
    @TedHopp Technically this is the exact opposite of that question. – biziclop Jul 02 '12 at 15:35
  • This isn't about the *interface* method being static, but allowing my to make the *implementing* method static. So I could call `MyImplementation.getInstance("foo");` instead of `new MyInterface("foo").getInstance("foo");` – KidTempo Jul 02 '12 at 15:36
  • you are trying to do not-conforming-inheritance and static methods. Does Java support non-conforming-inheritance? – ctrl-alt-delor Jul 02 '12 at 15:37
  • 2
    Note that in your example the signature of the static override does not match the signature of the interface method. This is not even a valid override. – Tudor Jul 02 '12 at 15:48

4 Answers4

9

Invoking static methods in Java requires you to specify the exact type. It is not possible to invoke static methods polymorphically, eliminating the need for @Override.

Please note that this approach is not universal across all languages: for example, you can override class methods in Objective-C, and Apple's cocoa frameworks make good use of this mechanism to customize their "factory" classes. However, in Java, C++, and C# class methods do not support polymorphic behavior.

Theoretically, Java designers could have let you provide interface method implementations through static methods in case an implementation does not need to access the state from the instance. But the same behavior is simple to achieve with a trivial wrapper:

public class MyImplementation implements MyInterface {
    public MyImplementation(String name) {
    }
    @Override
    public MyInterface getInstance() { // static is not allowed here
        return getInstanceImpl();
    }
    public static getInstanceImpl() {
        return new MyImplementation(name)
    }
}

Java compiler could have done the same thing on your behalf, but seeing a static method implement an instance method is both unusual and confusing, so my guess is that Java designers decided against providing this "piece of magic".

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • +1 for mentioning that this isn't universal. It's the Java calling syntax makes this approach impossible, not a theoretical boundary. – biziclop Jul 02 '12 at 16:00
1

Static methods cannot be subject to polymorphic behavior. That would not make much sense. Image this use case, assuming what you want would be possible:

public void foo(MyInterface i) {
    i.getInstance("abc");
}

now I want to call this method with an implementation of MyInterface (class A), but since I cannot pass the class itself, I need to pass an object:

A a = new A();
foo(a);

now inside foo the static override of getInstance is called on the instance of class A. So now I am stuck with creating an object just to call a static method.

My point is that you would still be constrained to create an object in most use cases of polymorphism since in your original interface the method was an instance method.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • "That would not make much sense" : it would - and it would be damn useful too. The question is why it's not implemented : http://stackoverflow.com/questions/20291984/why-is-overriding-of-static-methods-left-out-of-most-oop-languages. See this for how would one call those overrides – Mr_and_Mrs_D Nov 29 '13 at 23:47
0

because implementing an interface makes the implementor the type of the interface. That means instances need to have the methods defined by the type, not the class of the instances.

To put it another way,

public void mymethod

and

public static void mymethod

are NOT the same method declaration. They are completely distinct. If mymethod is defined on an interface, having the second definition simply does not satisfy implementing the interface.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
0

The answer comes down to what it means to implement an interface. When a class implements an interface, that is a promise that every instance of the class will respond to every method in the interface. When you implement the method as static, you make it possible to call the method without an instance of the class - but that doesn't fulfill the inheritance implementation's promise that the method will be callable on every instance of the class.

Iain
  • 4,203
  • 23
  • 21