Per этот ответ и этот ответ, статические методы Java не являются виртуальными и не могут быть переопределены. Поэтому интуитивно это должно работать (даже если в 99% случаев это опасное программирование):
class Foo
{
public static String frob() {
return "Foo";
}
}
class Bar extends Foo
{
public static Number frob() {
return 123;
}
}
Однако на практике это вам:
Foo.java:10: frob() in Bar cannot override frob() in Foo; attempting to use incompatible return type
found : java.lang.Number
required: java.lang.String
public static Number frob() {
^
Наивно, кажется, что Foo.frob()
и Bar.frob()
не должны иметь ничего общего друг с другом; но Java настаивает на том, что они это делают. Почему?
(Nb: Я не хочу слышать, почему было бы плохой идеей кодировать этот путь, я хочу услышать, что он на Java и/или дизайн JVM делает это ограничение необходимым.)
Обновлено для добавления:. Для тех, кто думает, что компилятор запутается, вызвав статические методы в экземплярах, если вы разрешите это: это не будет. Это уже нужно понять в случае совместимости сигнатур метода:
class Foo
{
static String frob() {
return "Foo";
}
}
class Bar extends Foo
{
static String frob() {
return "Bar";
}
}
class Qux {
public static void main(String[] args) {
Foo f = new Foo();
Foo b = new Bar();
Bar b2 = new Bar();
System.out.println(f.frob());
System.out.println(b.frob());
System.out.println(b2.frob());
}
}
получает вас:
Foo
Foo
Bar
Вопрос: какая конкретная причина, почему это не могло так легко (в случае с несовместимыми сигнатурами) получить вас:
Foo
Foo
123