В Java статические методы не унаследовали (или право слово переопределены), но они могут быть скрыты .
Большое значение здесь заключается в том, что они не подвергаются полиморфизму в качестве метода объекта.
public class C1 {
static public void M1() {
System.out.println("C1.M1().");
}
static public void main(String ... Args) {
M1();
}
}
public class C2 extends C1 {
static public void M1() {
System.out.println("C2.M1().");
}
static public void main(String ... Args) {
M1();
C1.main(Args);
}
}
C2.main(null)
При запуске, вы получите:
C2.M1().
C1.M1().
Как вы можете видеть,
вызова M1()
в C1.main (...) относятся к M1 C1 и
, вызывающий M1()
в C2.main (...), относится к M1 из C2.
Вызов M1 (без какого-либо префикса, см. Первую строку каждого main()
), не подвергаются полиморфизму, поскольку M1 в C1 не переопределяется C2.
Но вызов из С2 относится к М1 С2 как М1 С2 - Скрыть тот, что в C1.
Подробнее here.
EDIT: Я только что перечитал ваш вопрос и просто просмотрю часть о «хорошей практике программирования».
Как я уже говорил, статический метод не наследуется, а скрывается, поэтому он не хуже другого.
С точки зрения кода, они совершенно разные методы.
Скажем.
C1 has static method M1.
C2 extends C1 and has static method M1.
C3 extends C2.
При вызове M1 (без префикса) из C1 вы вызываете C1.M1(). При вызове M1 (без префикса) из C2 вы вызываете C2.M1().// выводить, но спрятаться При вызове M1 (без префикса) из C3 вы вызываете C3.M1(). // не извлекать и не скрытые
Чтобы указать, какой метод, используйте имя класса как C1.M1()
, C2.M1()
и C3.M1()
(это называется C2.M1()
).
Таким образом, эта реализация позволяет переопределять статический метод, но только как другой метод, а не как переопределенный (или заменяющий) метод.
Таким образом, это обычно не отличается от того, чтобы называть их по-другому: C1_M()
и C2_M()
.
Итак, вы можете спросить, зачем беспокоиться об этой функции? Я действительно не знаю. Возможно, это позволяет использовать более гибкий метод именования.
Но есть использование (которое могло бы или не было намерено), которое я использовал, это полиморфизм через отражение.
Поскольку вы можете получить метод по имени с помощью отражения, позволяя им иметь одно и то же имя, это позволит полиморфизм, когда это происходит через отражение.
Например (rought код, может не работать):
String aClsName = "C1"; // "C2";
Class aCls = Class.forName(aClsName);
Method aMth = aCls.getMethod("M1"); // M1 of C1 or C2 depends on the class name.
aMth.invoke(null);
ИЛИ
Object aObj = new C1(); // new C2();
Class aCls = aObj.getClass();
Method aMth = aCls.getMethod("M1"); // M1 of C1 or C2 depends on the class of the object.
aMth.invoke(null);
Когда думаю об этом, я думаю, что Java имеет использовать это тоже (как, writeObject(...)
для сериализации), так он может быть намерен.
Таким образом, скрытый статический метод не является хорошей практикой программирования (Eclipse также рекомендует против него), но он может быть полезен в двух случаях: (1) назвать метод точным, что он должен делать, и (2) полиморфировать его с помощью отражения.
Надеюсь, это поможет.
Я думаю, что Статические методы унаследованы. В качестве ответа я прилагаю код ниже. Вы можете это объяснить? – Geek
Существует несколько терминов, которые можно смутить здесь. наследовать, выводить, переопределять, скрывать, перегружать. В этом случае статические методы наследуются в том смысле, что вы можете использовать его в подклассе (поэтому я могу вызвать C3.M1(), и он будет вызывать C2.M1(), когда C3 не имеет M1), но в книге OOP, возможно, слово inherit также подразумевает полиморфизм, который мой ответ объясняет, что это не так для статического метода. Статический метод не позволяет переопределить, таким образом, они не подвергаются полиморфизму. Поэтому я сказал, что статические методы не наследуются в этом смысле (они могут быть получены). Это вопрос терминологии – NawaMan