Если статические методы не могут быть переопределены, как это работает здесь (для Java)?
Я понял, что статические переменные и статические методы относятся к классу, а не к объектам класса. Поэтому Override
статического метода не будет работать в Java, так как для переопределения нам нужен экземпляр класса, который будет создан. Но сегодня я что-то пробовал, что противоречило моим знаниям Java.
Пожалуйста, следуйте этому коду:
class Parent{
public static void doIt(){
System.out.println("In static method 'doit' of class Parent ");
}
}
class Child extends Parent{
public static void doIt(){
System.out.println("In static method 'doit' of class Child ");
}
}
public class StaticPractise{
public static void main(String[] args){
Parent.doIt();
Child.doIt();
}
}
Результат реализации выше:
D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Child
Из этого вывода я могу понять, что, хотя класс Child
расширяет класс Parent
, методы doit
являются индивидуальными для каждого класса, так как они static
. Поэтому не допускается их переопределение.
Теперь, пожалуйста, следуйте приведенному ниже коду, где @Override
добавляется к методу child doit
:
class Parent{
public static void doIt(){
System.out.println("In static method 'doit' of class Parent ");
}
}
class Child extends Parent{
@Override // Adding this annotation here
public static void doIt(){
System.out.println("In static method 'doit' of class Child ");
}
}
public class StaticPractise{
public static void main(String[] args){
Parent.doIt();
Child.doIt();
}
}
Результат приведенного выше кода дает ошибку компиляции следующим образом:
D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:31: error: method does not override or implement a method from a supertype
@Override
^
1 error
Здесь ясно сказано, что аннотация Override
не может применяться в методах static
, поскольку они не становятся переопределенными.
Теперь, пожалуйста, следуйте приведенному ниже коду, где Child
не имеет метода doit
:
class Parent{
public static void doIt(){
System.out.println("In static method 'doit' of class Parent ");
}
}
class Child extends Parent{ /* no doIt method */ }
public class StaticPractise{
public static void main(String[] args){
Parent.doIt();
Child.doIt();
}
}
Вывод:
D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Parent
Почему этот код компилируется и запускается? Я ожидал ошибку компиляции для метода doit
для класса Child, и я ожидал, что "Метод не найден". Я не понимаю.
Также следуйте приведенному ниже коду. Здесь метод doit
в Parent
теперь final
.
class Parent{
public static final void doIt(){ // now final
System.out.println("In static method 'doit' of class Parent ");
}
}
class Child extends Parent{
public static void doIt(){
System.out.println("In static method 'doit' of class Parent ");
}
}
public class StaticPractise{
public static void main(String[] args){
Parent.doIt();
Child.doIt();
}
}
Выход после запуска вышеуказанного кода выглядит следующим образом:
D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:30: error: doIt() in Child cannot override doIt() in Parent
public static void doIt(){
^
overridden method is static,final
1 error
D:\Rahul Shivsharan\MyPractise\JAVA>
Я ожидал, что вышеприведенный код должен работать нормально, поскольку методы doit
являются статичными в каждом классе, поэтому даже ключевое слово final
не должно компилировать ошибку, поскольку метод static
.
Пожалуйста, объясните мне, как метод переопределяет работу в статических классах на Java.
- Можно ли переопределить статические методы? Если да, то как закончится аннотация
@Override
?
- Если статические методы не могут быть переопределены, тогда как мой третий блок кода работает нормально?
- Если статические методы не могут быть переопределены, то почему ключевое слово
final
имеет значение?
Ответы
Ответ 1
Прежде всего, здесь задействованы различные механизмы: Переопределение и тени (также называемое скрытием).
1)
Статические методы не могут быть переопределены, поскольку они привязаны к классу, в котором они определены. Однако вы можете shadow/hide статический метод, как вы это делаете, с классом Parent
/Child
. Это означает, что метод заменяется в классе Child
, но по-прежнему доступен из класса Parent
.
Более очевидно, что вы не переопределяете, когда вызываете статические методы из экземпляров этих классов (и не используете вызов Class.staticMethod()
).
Parent parent = new Parent();
Child child1 = new Child();
Parent child2 = new Child();
parent.StaticMethod();
child1.StaticMethod();
child2.StaticMethod();
вывод
Static method from Parent
Static method from Child
Static method from Parent
Ответ - это отправка методов. Здесь вы можете взять исходный код
2)
Отправка находит метод в классе Parent
. Динамической отправки нет, так как тип runtime используется для поиска дескриптора метода. Он использует тип времени компиляции. Напомним: вызов статических методов из экземпляров считается плохой практикой, поскольку такие вещи, как описано выше, могут быть пропущены.
3)
С помощью final
вы заявляете, что метод не может быть переопределен и не скрыт/скрыт.
Ответ 2
Вы вводите в заблуждение переопределение с hiding
Ответ 3
Хотя в одном сообщении не рекомендуется задавать 3 вопроса, я все еще готов ответить на них.
-
Статические методы не могут быть переопределены, потому что нет смысла делать это. В вашем случае, если вы хотите переопределить статический метод, вы можете просто вызвать этот метод и добавить его после этого или просто создать другой метод.
-
Итак, теперь вы знаете, что статические методы нельзя переопределить. Но вы спрашиваете, почему работает третий код? Третий код - это код с
Открытый класс Child extends Parent {}
правильно? Хотя статические методы нельзя переопределить, их можно унаследовать. То, что вы делаете, наследует Parent
, так что это нормально!
- Теперь позвольте мне сказать вам, что в первом примере кода вы скрываете метод в классе
Parent
, а не переопределяете. Вот почему вы получаете результат. Ключевое слово final
означает, что метод может никогда не меняться, даже не скрываться. Поэтому почему.