Reputation: 2746
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.
Upvotes: 2
Views: 432
Reputation: 2524
Abstract methods are supposed to be overridden (Defined) by a subclass method. You can't override static methods as they do not pertain to an instance but to the specific class they are defined.
For example a non static method is used as such:
Foo b = new Baz();
Object result = b.bar();
static is used as such:
Object result = Baz.bar2();
if you really want bar to be static and also an override at the instance level do this:
public interface Foo {
Object bar();
}
public class Baz implements Foo {
@Override
public Object bar() {
return Baz.bar2();
}
public static Object bar2() {
//your implementation
}
}
Upvotes: 1
Reputation: 38625
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
.
Upvotes: 3
Reputation: 46428
public class Baz implements Foo {
public Object bar() {
//My implementation
}
public static Object bar() {
//My implementation
}
}
because, your method signatures are same, bar () is not overloaded. as you have declared a non-static bar() in your abstract class, you are forced to implement that method in this class.
Upvotes: 1