Наследование в статических методах - PullRequest
10 голосов
/ 14 февраля 2011

Почему приведенный ниже код выводит «Main»?

public class Main
{
    public static void method()
    {
        System.out.println("Main");
    }

    public static void main(String[] args)
    {
        Main m = new SubMain();
        m.method();
    }
}

class SubMain extends Main
{
    public static void method()
    {
        System.out.println("SubMain");
    }
}

Во время выполнения m указывает на экземпляр Submain, поэтому он должен концептуально напечатать «SubMain».

Ответы [ 5 ]

18 голосов
/ 14 февраля 2011

Статические методы разрешаются в типе переменной во время компиляции. m имеет тип Main, поэтому вызывается метод в Main.

Если вы измените его на SubMain m ..., будет вызван метод на SubMain.

15 голосов
/ 14 февраля 2011

Это потому, что статические методы не полиморфны.Более того, статический метод должен вызываться не объектом, а с использованием класса, то есть Main.method() или SubMain.method().Когда вы звоните m.method() java фактически вызывает Main.method(), потому что m имеет тип Main.

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

2 голосов
/ 14 февраля 2011

Eclipse выдает мне предупреждение такого рода, когда я пытаюсь сделать что-то подобное:

Статический метод XXX () типа XXX должен быть доступен статическим способом

Статические методы не участвуют в наследовании.Переменная имеет тип Main, поэтому компилятор разрешил вызов вашей функции в Main.method().

. Для большего удовольствия попробуйте установить m в null.

1 голос
/ 14 февраля 2011

Java выполняет раннее связывание для статических методов, в отличие от методов экземпляров, которые динамически связаны.

Поскольку переменная вашего объекта имеет тип Main, вызов связан с реализацией суперкласса во время компиляции.

Хорошее объяснение доступно здесь .

0 голосов
/ 15 июня 2014

статические методы статически связаны с их именем класса, потому что m является типом класса Main тогда после компиляции это будет выглядеть следующим образом Main.method (); после компиляции вашего класса выполните следующую команду javap -c Главная Вы можете увидеть код сборки JVM для основного класса и вы увидите следующее m.method // вызывать статический вызывать статические, вызывать специальные говорит о том, что статическая привязка invoke special, invoke interface сообщает, что динамическое связывание

...