Search code examples
javainheritanceabstract-methods

Why can't I make an abstract method static in my implementation?


Let's assume the following scenario in Java

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
}

Why can I not make Baz.bar() static?

Doing so results in the compiler error This static method cannot hide the instance method from Foo Adding an @Override annotation to Baz.bar() changes the compiler error to The method bar() of type Baz must override or implement a supertype method

It seems to me that from the perspective of anyone using the interface Foo, the implementing class Baz would still fulfill the interface requirements, while making a method that has a static implementation available to anyone who is explicitly using the Baz class without instantiation.

How come the compiler doesn't allow this scenario?

Edit:

Maybe I wasn't clear enough, but what I'm actually asking is why this isn't allowed, since from my point of view, I'm not decreasing the visibility of the interface-defined method.

And yes, I know I used the word abstract in the title, and not in the question, but that's because the abstract keyword is implied in an interface.

Edit 2:

I'll add an example that is closer to reality for clarity on why I am even asking this:

public interface DatabaseMapper<T extends DatabaseType> {
    Entry<T> convert(Entry);
}

public interface SQL extends DatabaseType {}

public class SQLEntry implements Entry<SQL> {}

public class SQLMapper implements DatabaseMapper<SQL> {
    public SQLEntry convert(Entry e) {
        //Convert some generic entry to the SQLEntry type
    }
}

In this case, I want to force all Mapper implementations to implement the convert method, but at the same time, this method might not depend in any way on the internal state of an SQLMapper object, and it might be desirable to be able to convert a generic Entry into a SQLEntry without going through an instantiation-process that probably includes database connection strings and the like.

This was the scenario I was faced with, and why I wanted to see if anyone knew why this was not possible to accomplish with the same method - e.g. not having to resort to a public static SQLEntry convertStatic(Entry e) which the overridden method delegates its implementation to.

Again though, I understand that this is not possible in Java due to how the compiler works - I am simply trying to understand why that is.


Solution

  • The real answer is that Java simply wasn't defined this way. In other language, this is possible.

    For instance, in Scala there aren't static methods, but you can instead define static object that are singleton and that allow this. In dynamic language like Smalltalk or Ruby, classes are like objects, and this is also possible.

    But in Java, static methods are similar to global methods. There is not concept of self, nor super in a static method because it's not bound to an object. By consequence inheritance/overriding doesn't really apply.

    It unfolds that if there is no notion of inheritance, it also doesn't make sense to speak of abstract.