2014-02-15 3 views
2

Я не могу понять, почему компилятор выдает ошибку при попытке скомпилировать этот код:Является ли Java предотвращением переопределения статических методов?

class A 
{ 
    public static void f() 
    { 
     System.out.println("A.f()"); 
    } 
} 

class B extends A 
{ 
    public static int f() 
    { 
     System.out.println("B.f()"); 
     return 0; 
    } 
} 

Почтение между двумя methodes в A и B классов является тип возвращаемого значения, я прочитал, что Java предотвратить переопределение статические методы. Так что я ожидаю, что компилятор не должен показывать никаких ошибок, потому что изначально не происходит переопределение!

+1

Это не переопределяет проверку правил переопределения .... first f method возвращает void() второй метод f возвращает int – Naren

+1

Да, но компилятор говорит, что есть ошибка ??! – BBeta

ответ

6

Java Language Specification имеет следующее правило:

8.4.8.3. Требования в переопределении и скрытии

Если объявление метода d1 с типом возврата R1 перекрывает или скрывает декларацию другого метода d2 с типом возвращаемого значения R2, ​​то d1 должен быть заменен на возвращаемый тип (§8.4.5) для d2, или возникает ошибка времени компиляции.

Это правило допускает ковариантные типы возврата - уточнение возвращаемого типа метода при его переопределении.

Таким образом, даже если метод скрывает один из суперклассов и не отменяет его, возвращаемый тип все еще должен быть совместимым.

2

Метод в классе B не переопределяет метод в классе A, как вы уже знаете. проблема в том, что у вас есть два разных метода для класса B с той же подписью. Помните, что тип возврата не считается частью сигнатуры метода.

От JLS §8.4.2 - Method Signature:

два метода имеют одинаковую сигнатуру, если они имеют одинаковые имена и типы аргументов.

Таким образом, метод в классе B не является ни действительным переопределением, ни действительной перегрузкой. Поскольку перегрузка требует, чтобы у вас была другая сигнатура методов, которых у вас нет.

Кроме того, это не является допустимым методом скрытия, поскольку для этого требуется, чтобы тип метода возврата возвращался так же, как или подтип возвращаемого типа метода суперкласса. Это также не происходит здесь.

Таким образом, измените тип возвращаемого класса класса B на void и измените его подпись.

+0

Это не перегрузка, она скрывается. из-за статического –

Смежные вопросы