3

問題を説明する適切な要約が見つかりません (提案を歓迎します)

次の2つのクラスがあります。

テスト1

import java.lang.reflect.Method;

abstract class Test1 {

    boolean condition = true;

    public void f() {
        System.out.println("Test1 : f");
    }

    public void g() {
        System.out.println("Test1 : g");
        f();
        if (condition) {
            f(); // call Test1.f() here. HOW?

            // Following didn't work
            try {
                Method m = Test1.class.getDeclaredMethod("f");
                m.invoke(this);
            } catch (Exception e) {
                System.err.println(e);
            }
        }
    }
}

テスト2

class Test2 extends Test1 {

    public void f() {
        System.out.println("Test2 : f ");
    }

    public static void main(String[] args) {
        Test2 t2 = new Test2();
        t2.g();
    }

}

出力は次のとおりです。

Test1 : g
Test2 : f
Test2 : f
Test2 : f

condition問題は、フィールド inによって与えられた特別な条件により、のオブジェクトを使用して呼び出しているにもかかわらず、 inTest1を呼び出したいことです。Test1f()g()Test2

リフレクションを試しましたが、うまくいきません。助言がありますか?

EDIT 1: 具体的には言及しませんでしたが、よく見ると Test1 は抽象的です。そのため、そのオブジェクトを作成できません。

4

6 に答える 6

3

構築しようとしているロジックを真剣に検討する必要があります。子クラスでメソッド f をオーバーライドしようとした理由には、その背後に確かな理由があります。

または、メソッド f からの戻り値としてブール値を使用し、子メソッドで使用することもできboolean r = super.f(); if(r){//execute child logic.}ます。これにより、問題が解決するはずです。

于 2013-01-16T12:08:56.403 に答える
2

私が理解したもの。

あなたの質問:クラスでメソッドを呼び出している
場合は、なぜ子 (Test2) クラスを実行しているのか。g()f()Test1f()

回答: JLS-8.4.8.1 から

サブクラス Test2は、Test1f()のメソッドをオーバーライドする単一のメソッドを宣言します。 クラス Test1 から f()メソッドを継承します。g()

この例のオーバーライドに関する重要な点は、クラス Test1 で宣言されているメソッドが、現在のオブジェクトによって定義されているメソッドg()を呼び出すことです。これは、クラス Test1 で宣言されているメソッドである必要はありません。f()thisf()

したがって、g()メインで Test2 オブジェクト t2 を使用して が呼び出された場合、メソッドf()の本体での の呼び出しは、オブジェクト t2 の の呼び出しです。これにより、Test1 のサブクラスは、メソッドを再定義せずにメソッドの動作を変更できます。g()f()f()

脳震盪:

したがって、一部のクラスがその親のメソッドをオーバーライドしている場合、コントラクトは、拡張するように設計された Test1 は、クラスとそのサブクラスの間のコントラクトを明確に示す必要があり、サブクラスがf()この方法でメソッドをオーバーライドできることを明確に示す必要があります。 .

于 2013-01-25T11:33:06.933 に答える
1

Test1 にメソッド f2 を追加します。

private void f2() {
    System.out.println("Test1 : f");
}
public void f() {
    this.f2()
}

このようにして、条件が真のときに f2() を呼び出すことができます。

于 2013-01-16T12:07:15.017 に答える
0

UPD:あまり注意を払っていないその人のために、私が説明します。

以下のコードでは、角かっこを使用して新しい匿名{ }クラスを作成しています。これにより、サブクラス化された の新しいインスタンスを作成できますTest1


を使用する代わりに、次のreflectionような面白いことを行うことができます。

public void g() {
    System.out.println("Test1 : g");
    f();
    if (condition) {
         new Test1(){}.f();
    }
}

唯一の欠点は、そのf()ような方法で呼び出されたメソッドが、まったく別のオブジェクトのメソッドを呼び出していることです。

于 2013-01-16T12:23:00.147 に答える
0

メソッド名が同じ場合、それはできません。
別の方法として、super.f() を使用して、サブクラスでスーパー クラス メソッドを直接呼び出すこともできます。

于 2013-01-16T12:11:20.853 に答える
0

継承では、動作の継承super.f()、オーバーライド、@Overrideまたはその両方のみが可能です

@Override
public void f(){
    super.f(); 
    //do something  
}

メソッドをオーバーライドしてから、オーバーライドされる前に親メソッドの状態を呼び出すことはできません。継承はそのようには機能しません。

于 2013-01-16T12:44:52.713 に答える