Суперкласс не вызывает переопределенный метод? - PullRequest
6 голосов
/ 10 апреля 2009

У меня есть следующие классы:

class foo {
    public void a() {
        print("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        print("overwritten a");
    }
}

Когда я сейчас вызываю bar.b (), я хочу, чтобы он вызывал переопределенный метод a () в foo. Тем не менее, он печатает «а».

Ответы [ 7 ]

10 голосов
/ 10 апреля 2009

Ваши два класса в разных пакетах? И объявлены ли ваши методы класса foo общедоступными, защищенными, приватными или пакетными локальными? Очевидно, что если они являются частными, это не сработает. Возможно, менее очевидным является то, что если они являются локальными (то есть не имеют публичной / защищенной / закрытой области видимости), вы можете переопределить их, только если вы находитесь в том же пакете, что и исходный класс.

Например:

package original;
public class Foo {
  void a() { System.out.println("A"); }
  public void b() { a(); }
}

package another;
public class Bar extends original.Foo {
  void a() { System.out.println("Overwritten A"); }
}

package another;
public class Program {
  public static void main(String[] args) {
    Bar bar = new Bar();
    bar.b();
  }
}

В этом случае вы все равно получите «А». Если вы объявите оригинальный метод a () в публичном или защищенном Foo, вы получите ожидаемый результат.

9 голосов
/ 10 апреля 2009

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

Хороший способ проверки - добавить аннотацию @Override в bar.a () и посмотреть, не выдаст ли компилятор ошибку, что () на самом деле ничего не перекрывает

7 голосов
/ 10 апреля 2009

Когда я запускаю следующее:

public class Program {
    public static void main(String[] args) {
        bar b = new bar();
        b.b();
    }
}

class foo {
    public void a() {
       System.out.printf("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        System.out.printf("overwritten a");
    }
}

Я получаю следующий вывод:

overwritten a

что я и ожидал увидеть.

1 голос
/ 10 апреля 2009

Методы определены как статические? Это единственный способ получить такой результат. Я нашел хорошее объяснение этому здесь: http://faq.javaranch.com/view?OverridingVsHiding

0 голосов
/ 31 октября 2012

Когда я работал над программой для Android, у меня была та же проблема с моими классами Java. Оказалось, что проблема не в классах, а в том, как фреймворк Android обрабатывает вывод на экран.

например, если выход был запрограммирован в методе onCreate () в родительском классе, Android не смог правильно извлечь выходные данные переопределенных методов из дочерних классов за пределами первого дочернего. Честно говоря, я не понимаю весь порядок вызова методов.

Чтобы решить эту проблему, я просто запрограммировал вывод в onResume (), и теперь он, кажется, работает нормально.

0 голосов
/ 15 июля 2011

Изо рта лошади:

http://download.oracle.com/javase/tutorial/java/IandI/override.html

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

Так что, если они оба являются статическими методами, и вы вызываете метод из суперкласса, то вызывается метод суперкласса, а не метод подкласса. Так что на самом деле никакого переопределения не происходит.

0 голосов
/ 10 апреля 2009

Вы можете быть смущены, если вы пришли из C # или другого языка, где вам нужно явно объявить виртуальные функции и / или переопределяющие функции.

В Java все функции экземпляра являются виртуальными и могут быть переопределены - если они не объявлены как частные и / или окончательные.

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

Пример Эндрю показывает, как это должно работать.

...