6

私は次のクラスを持っています:

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

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

ここでbar.b()を呼び出すとき、fooでオーバーライドされたメソッドa()を呼び出すようにします。ただし、「a」は出力されます。

4

7 に答える 7

10

2 つのクラスは異なるパッケージに入っていますか? foo クラスのメソッドは public、protected、private、または package local と宣言されていますか? 明らかに、それらがプライベートである場合、これは機能しません。おそらくあまり明白ではありませんが、それらがパッケージ ローカル (つまり、public/protected/private スコープがない) の場合、元のクラスと同じパッケージにいる場合にのみオーバーライドできます。

例えば:

パッケージオリジナル;
公開クラス Foo {
  void a() { System.out.println("A"); }
  public void b() { a(); }
}

別のパッケージ;
public class Bar extends original.Foo {
  void a() { System.out.println("上書きされた A"); }
}

別のパッケージ;
公開クラス プログラム {
  public static void main(String[] args) {
    バー バー = 新しいバー();
    bar.b();
  }
}

この場合でも、「A」が返されます。元の a() メソッドを Foo public または protected で宣言すると、期待した結果が得られます。

于 2009-04-10T04:05:32.787 に答える
9

オーバーライドされないため機能しない静的メソッドを使用しようとしている可能性があります。

@Override アノテーションを bar.a() に追加して、a() が実際には何もオーバーライドしていないというエラーがコンパイラーから出されるかどうかを確認することをお勧めします。

于 2009-04-10T03:16:55.867 に答える
7

次を実行すると:

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

これは私が期待するものです。

于 2009-04-10T03:03:17.600 に答える
1

メソッドは静的として定義されていますか? それが、その結果を得ることができる唯一の方法です。ここでそれについての良い説明を見つけました: http://faq.javaranch.com/view?OverridingVsHiding

于 2009-04-10T03:16:50.080 に答える
0

馬の口 より:

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

「呼び出されるオーバーライドされたメソッドのバージョンは、サブクラスのものです。呼び出される隠しメソッドのバージョンは、スーパークラスまたはサブクラスから呼び出されるかによって異なります。」

したがって、両方とも静的メソッドであり、スーパー クラスからメソッドを呼び出すと、サブクラス メソッドではなく、スーパー クラス メソッドが呼び出されます。実際、オーバーライドは行われていません。

于 2011-07-15T04:31:00.347 に答える
0

仮想関数やオーバーライド関数を明示的に宣言する必要がある C# やその他の言語から来ている場合は、混乱する可能性があります。

Java では、すべてのインスタンス関数は仮想であり、オーバーライドできます (非公開または最終として宣言されている場合を除く)。

そのために新しい @Override アノテーションを指定する必要はありません。アノテーションを追加すると、意図がオーバーライドであることを指定するだけで、オーバーライドでない場合は警告またはエラーが発生します。(たとえば、誤ってメソッド名のスペルを間違えた場合)。

Andrew の例は、これがどのように機能するかを示しています。

于 2009-04-10T03:53:31.723 に答える
-1

Androidプログラムで作業しているときに、Javaクラスでも同じ問題が発生しました。問題はクラスではなく、Androidフレームワークが画面出力を処理する方法にあることが判明しました。

たとえば、出力が親クラスのonCreate()メソッドでプログラムされている場合、Androidは、最初の子を超えて子クラスからオーバーライドされたメソッドの出力を正しくフェッチできませんでした。正直なところ、メソッドの呼び出し順序全体がわかりません。

この問題を解決するために、onResume()で出力をプログラムしただけで、正常に動作しているように見えます。

于 2012-10-31T15:00:14.667 に答える