Вопрос-ответ

Are static methods inherited in Java?

Наследуются ли статические методы в Java?

Я читал Руководство программиста по сертификации Java ™ SCJP Халида Могола.

В главе о наследовании объясняется, что


Наследование членов тесно связано с их объявленной доступностью. Если член суперкласса доступен по его простому имени в подклассе (без использования какого-либо дополнительного синтаксиса, такого как super), этот член считается унаследованным


Также упоминается, что статические методы не наследуются. Но приведенный ниже код идеально подходит:

class A
{
public static void display()
{
System.out.println("Inside static method of superclass");
}
}

class B extends A
{
public void show()
{
// This works - accessing display() by its simple name -
// meaning it is inherited according to the book.
display();
}
}

Как я могу напрямую использовать display() в классе B? Более того, B.display() также работает.

Объяснение книги применимо только к методам экземпляра?

Переведено автоматически
Ответ 1

Все доступные методы наследуются подклассами.

Из учебников Sun Java:


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


Единственная разница между унаследованными статическими методами (класса) и унаследованными нестатическими методами (экземпляра) заключается в том, что когда вы пишете новый статический метод с той же сигнатурой, старый статический метод просто скрывается, а не переопределяется.

С страницы о разнице между переопределением и скрытием.


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


Ответ 2

Вы можете ощутить разницу в следующем коде, который немного отличается от вашего кода.

class A {
public static void display() {
System.out.println("Inside static method of superclass");
}
}

class B extends A {
public void show() {
display();
}

public static void display() {
System.out.println("Inside static method of this class");
}
}

public class Test {
public static void main(String[] args) {
B b = new B();
// prints: Inside static method of this class
b.display();

A a = new B();
// prints: Inside static method of superclass
a.display();
}
}

Это связано с тем, что статические методы являются методами класса.

A.display() и B.display() будут вызывать методы своих соответствующих классов.

Ответ 3

Статические методы в Java наследуются, но не могут быть переопределены. Если вы объявляете тот же метод в подклассе, вы скрываете метод суперкласса вместо того, чтобы переопределять его. Статические методы не являются полиморфными. Во время компиляции статический метод будет статически связан.

Пример:

public class Writer {
public static void write() {
System.out.println("Writing");
}
}

public class Author extends Writer {
public static void write() {
System.out.println("Writing book");
}
}

public class Programmer extends Writer {

public static void write() {
System.out.println("Writing code");
}

public static void main(String[] args) {
Writer w = new Programmer();
w.write();

Writer secondWriter = new Author();
secondWriter.write();

Writer thirdWriter = null;
thirdWriter.write();

Author firstAuthor = new Author();
firstAuthor.write();
}
}

Вы получите следующее:

Writing
Writing
Writing
Writing book
Ответ 4

Если это то, что действительно говорится в книге, это неправильно.[1]

В спецификации языка Java # 8.4.8 говорится:


8.4.8 Наследование, переопределение и скрытие


Класс C наследует от своего прямого суперкласса все конкретные методы m (как статические, так и экземплярные) суперкласса, для которых верно все нижеперечисленное:



  • m является членом прямого суперкласса C.


  • m является общедоступным, защищенным или объявленным с доступом к пакету в том же пакете, что и C.


  • Ни один метод, объявленный в C, не имеет сигнатуры, которая является подзаголовком (§8.4.2) сигнатуры m .



[1] В моей копии, 1-м издании, 2000 г. этого не сказано.

java inheritance