2013-08-04 3 views
1

Так что я знаю, что в Java, когда у вас есть статический метод вы должны назвать его с форматом ClassName.method(), а не использовать ту же структуру, как для методов экземпляра, а именно:Наследование статических методов в Java?

ClassName myObject = new ClassName(); 
myObject.method(); 

Однако, если вы должен был сделать это таким образом, он все равно будет действительным кодом и будет работать. Допустим, я решил сделать это, где рассматриваемый метод является статическим, и имеют следующие настройки:

public SuperClass { 
    public static int foo(int x) { 
     return x; 
    } 
} 

public SubClass extends SuperClass { 
    public static int foo(int x) { // Overriding foo() in SuperClass 
     return x + 1; 
    } 
} 

public MyDriver { 
    public static void main(String[] args) { 
     SuperClass myObject = new SubClass(); // Upcasting. 
     System.out.println(myObject.foo(5)); // This should polymorphically print 6 
    } 
} 

Что печатает на экране, однако, 5, а не 6. Почему?

ответ

5

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

Когда вы звоните myObject.foo(5), вы вызываете SuperClass.foo(5) в действительности, потому что вы объявили myObject как SuperClass, независимо от того, инстанцирован ли вы его как единое целое.

Правильный способ вызвать статический метод, чтобы вызвать непосредственно из класса, она объявлена ​​в, так что если вы хотите позвонить SubClass.foo(), вы должны вызвать его из явно объявленного SubClass экземпляра (то есть нет upcasting), или вам нужно позвонить SubClass.foo() так.

Простой ответ заключается в том, что вызов статических методов из экземпляров оценивает вызов тех же методов из объявленного типа без экземпляра, а не типа экземпляра.

Я не уверен в этом, но я не удивлюсь, если когда код будет скомпилирован в байтовый код, то вызов статического метода экземпляра будет фактически скомпилирован в прямой вызов объявленного типа.

Редактировать: Первосвященство привлекло мое внимание к этому, и я очистил объяснение, чтобы сделать его более понятным и исправить некоторые незначительные грамматические ошибки с моей стороны. Надеюсь, это поможет будущим читателям.

1

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

myObject.foo(5) 

только ярлык, что вы действительно делаете

SuperClass.foo(5) 
+0

Это на самом деле не только один экземпляр, это один на виртуальной машине, если у вас есть более чем одну виртуальную машину, вы можете иметь более одного экземпляра. – luisZavaleta

+2

+1, но в зависимости от архитектуры ClassLoader это может быть даже более одного на JVM; OSGi, например. – earcam

1

Использование экземпляров класса для вызова статических методов, класса является то, что вам следует избегать, так как это может привести к путанице. Если вам нужно вызвать любой метод полиморфно, сделайте его методом экземпляра. Полиморфно не вызывать статический метод. Причина, вызываемая вызовом SuperClass, заключается в том, что это явный класс myObject во время компиляции. Этот эффект также можно увидеть в следующем сценарии:

public void doSomething(SuperClass param) { 
    System.out.println("SuperClass"); 
} 

public void doSomething(SubClass param) { 
    System.out.println("SubClass"); 
} 

public void test() { 
    SuperClass myObject = new SubClass(); 
    doSomething(myObject); 
} 

Если тест) называется (, SuperClass будет напечатан.

0

Статические методы в JVM рассматриваются как глобальные, они вообще не связаны с экземпляром объекта. Кстати, вы можете только перегружать статические методы, но вы не можете переопределить. Поэтому проверьте на "Oracle Documentation for Overriding and Hiding Documents".

Определение метода с той же сигнатурой, как метод суперкласса в:

--------------------------- --------------Суперкласс экземпляра МетодСуперкласс Статический метод      
Подкласс Метод экземпляра            Переопределение                                                                          генерирует ошибка времени компиляции
Подкласс Статический метод                        генерирует ошибку во время компиляции      Скрытие                                                                                  

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