1

私はサードパーティのフレームワークを使用していますが、そのオブジェクトの一部をデリゲートとしてクラスの 1 つにラップする必要があることがわかりました。

class Foo { // 3rd party class.
    protected void method() {}
}

class FooWrapper extends Foo {
    private Foo mDelegate;

    public FooWrapper(Foo inDelegate) {
        mDelegate = inDelegate;
    }

    protected void method() {
        mDelegate.method(); // error can't access protected method() of mDelegate
    }
}

だから問題があります。このメソッドを内部オブジェクトに委任する必要がありますが、保護されているためアクセスできません。

この特定の問題を解決する方法についてのアイデアはありますか? これは Java 1.3 用です。

4

4 に答える 4

3

Foo の別のインスタンスを作成するのはなぜですか? FooWrapper は既に Foo です。

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

    protected void method() {
        super.method();
    }
}

編集:本当に別のインスタンスが必要な場合、1つの方法(少し醜いですが)はリフレクションを使用することです:

public class Foo {

    protected void method() {
        System.out.println("In Foo.method()");
    }
}

public class FooWrapper extends Foo {

    private Foo foo;

    public FooWrapper(Foo foo) {
        this.foo = foo;
    }

    public void method() {
        try {
            Method m = foo.getClass().getDeclaredMethod("method", null);
            m.setAccessible(true);
            m.invoke(foo, null);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Edit2:以下のコメントに基づいて、Foo の 2 つのサブクラスを用意します。1 つは保護されたメソッドのパブリック バージョンを提供するだけで、もう 1 つはすべての重要なメソッドをオーバーライドします。1 つ目は Foo とまったく同じように見え、動作します。2 つ目は必要なことを何でも実行できます。

public class Foo {

    protected void method() {
        System.out.println("In Foo.method()");
    }
}

public class DelegateFoo extends Foo {

    public void method() {
        super.method();
    }
}

public class FooWrapper extends Foo {

    private DelegateFoo foo;

    public FooWrapper(DelegateFoo foo) {
        this.foo = foo;
    }

    public void method() {
        foo.method();
        /* extra logic here */
    }
}
于 2009-12-07T18:03:04.463 に答える
2

私がこのような状況にあったときに私がしたことは、良くありませんが、うまくいきます.PublicFooをFooと同じパッケージに作成し(ただし、ソースに)、Fooを拡張し、保護されたメソッドを公開します。

これで、FooWrapper は PublicFoo を拡張して、やりたいことが何でもできるようになりました。

ただし、元の jar が署名されて封印されている場合は、展開する前に署名を削除する必要があることに注意してください。(jar のマニフェスト ディレクトリに移動し、証明書を削除するだけです)。

于 2009-12-07T18:03:07.833 に答える
0

そのプロパティ (ゲッターまたはパブリック変数) へのパブリック アクセスがある場合は、コピー コンストラクターを作成できます。

public FooWrapper(Foo inDelegate) {
    this.property1 = inDelegate.getProperty1();
    this.property2 = inDelegate.getProperty2();
    // for every property
}

プロパティがオブジェクトである場合は、元のオブジェクトからアクセスしたときに変更が表示されるため、さらに優れています。(つまり、これらのオブジェクトの 1 つを置き換えるまでは、String のような不変クラスの場合はそうしなければなりません。)

于 2009-12-07T18:33:24.013 に答える
-1

サブクラスは、スーパークラスの保護されたメソッドにアクセスできる必要があります。

mDelegate.method() の代わりに super.method() を呼び出すと、うまくいきます。親クラスラップしてインスタンス化しています。

于 2009-12-07T18:04:57.690 に答える