質問
私はサードパーティのフレームワークを使用していますが、そのオブジェクトの一部をクラスの 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 用です。
解決
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();
}
}
}
編集2: 以下のコメントに基づいて、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 */
}
}
他のヒント
私はこのような状況にあって、その素敵なていませんでしたときに私がやったが、それは動作しますが、Fooのと同じパッケージでPublicFooを作成する(ただし、あなたのソースで)され、それがfooを拡張する必要があり、および保護されたメソッドをオーバーライドし、それを公開する。
さて、FooWrapperはPublicFooを拡張し、あなたがやりたいことができます。
オリジナルのjarファイルが署名され、密封されている場合は、それをデプロイする前に、ただし、署名を削除するyoullの必要があります。 (あなたは瓶にマニフェストディレクトリに移動し、単に証明書を削除することができます)。
さて、あなたはコピーコンストラクタを作成することができます:
public FooWrapper(Foo inDelegate) {
this.property1 = inDelegate.getProperty1();
this.property2 = inDelegate.getProperty2();
// for every property
}
のプロパティがオブジェクトである場合は...、でも良く、素晴らしいので、あなたはあまりにも、元のオブジェクトを介してアクセスしたときに表示されます加えた変更! (あなたは文字列のような不変クラスのために持っているこれらのオブジェクトのいずれかを交換するまでそれは、です。)
サブクラスへのアクセスを持っている必要がありますスーパークラスの保護方法。
あなただけのsuper.methodを呼び出すと()の代わりにmDelegate.methodの()、それは行きますよ。あなたは、両方の親クラスをラップしているとのそれをインスタンスます。