it-swarm.com.ru

Статические методы наследуются в 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() также работает.

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

118
Algorithmist

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

От Солнца Java Учебники :

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

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

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

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

155
yincrash

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

Спецификация языка Java # 8.4.8 гласит:

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

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

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

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

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

[1] Это не говорит, что в моем экземпляре, 1-е издание, 2000.

14
user207421

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

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();
        b.display();

        A a = new B();
        a.display();
    }
}

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

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

8
Gaurav

B.display () работает, потому что статическое объявление делает метод/член принадлежащим классу, а не конкретному экземпляру класса (aka Object). Вы можете прочитать больше об этом здесь .

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

5
Kai

Эта концепция не так проста, как кажется. Мы можем получить доступ к статическим членам без наследования, которое является HasA-отношением. Мы можем получить доступ к статическим членам, также расширив родительский класс. Это не означает, что это ISA-отношение (наследование). На самом деле статические члены принадлежат классу, а static не является модификатором доступа. Пока модификаторы доступа разрешают доступ к статическим членам, мы можем использовать их в других классах. Например, если он публичный, он будет доступен внутри того же пакета, а также вне пакета. Для частного мы не можем использовать это нигде. По умолчанию мы можем использовать его только внутри пакета. Но для защищенных мы должны расширить суперкласс. Таким образом, получение статического метода для другого класса не зависит от того, является ли он статическим. Это зависит от модификаторов доступа. Так что, на мой взгляд, члены Static могут получить доступ, если позволят модификаторы доступа. В противном случае мы можем использовать их так же, как мы используем Hasa-отношение. И имеет отношение не наследство. Опять же мы не можем переопределить статический метод. Если мы можем использовать другой метод, но не можем переопределить его, то это HasA-отношение. Если мы не можем переопределить их, это не будет наследством. Так что автор был на 100% прав.

2
Noman_ibrahim

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

Но также верно и то, что статические функции-члены не участвуют в динамическом связывании. Если сигнатура этого статического метода одинакова как в родительском, так и в дочернем классе, то применяется концепция Shadowing, а не полиморфизм.

0
shubham

Статические методы в 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
0
Aleksey Bykov

Статический метод наследуется в подклассе, но это не полиморфизм. Когда вы пишете реализацию статического метода, родительский метод класса перезаписывается, а не переопределяется. Подумайте, если он не унаследован, то как вы можете получить доступ без classname.staticMethodname();?

0
user4016405

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

public class A {

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

public class B extends A {

    void show(){
        display();
    }

     public static void display(){
        System.out.println("in static method of B");
    }

}
public class Test {

    public static void main(String[] args){
        B obj =new B();
        obj.show();

        A a_obj=new B();
        a_obj.display();


    }


}

В первом случае o/p - это «в статическом методе B» # успешное переопределение Во втором случае, o/p - «в статическом методе A» # Статический метод - не будет учитывать полиморфизм

0
Manav Garekar

Статические методы наследуются в Java, но они не участвуют в полиморфизме. Если мы попытаемся переопределить статические методы, они просто скрывают статические методы суперкласса, а не переопределяют их. 

0
Praveen Kumar