我正在使用第三方框架,结果我需要将其一些对象包装为我的一个类的委托。
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。
答案 0 :(得分:3)
为什么要构建一个单独的Foo实例? FooWrapper已经是Foo。
class Foo {
protected void method() {}
}
class FooWrapper extends Foo {
protected void method() {
super.method();
}
}
编辑:如果你真的必须有单独的实例,一种方法(尽管有点丑陋)是使用反射:
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子类,一个只提供受保护方法的公共版本,另一个重写所有重要方法。第一个看起来和行为完全像一个Foo,第二个可以做你需要做的任何事情:
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 */
}
}
答案 1 :(得分:2)
当我遇到这样的情况时,我做了什么,它不好,但是它有效,是在与Foo相同的包中创建一个PublicFoo(但是在你的源代码中),让它扩展Foo,并覆盖受保护的方法并将其公开。
现在,FooWrapper可以扩展PublicFoo并做任何你想做的事。
但是,请注意,如果原始jar已签名并已密封,则需要先删除签名,然后才能部署它。 (您可以进入jar中的Manifest目录,只需删除证书)
答案 2 :(得分:0)
好吧,如果它具有对其属性的公共访问权限(可以是getter或公共变量),则可以创建一个复制构造函数:
public FooWrapper(Foo inDelegate) {
this.property1 = inDelegate.getProperty1();
this.property2 = inDelegate.getProperty2();
// for every property
}
如果属性是对象......很棒,甚至更好,因为当你通过原始对象访问时,你所做的任何更改都会显示出来! (也就是说,直到你替换其中一个对象,你必须使用像String这样的不可变类。)
答案 3 :(得分:-1)
超类的受保护方法的子类should have access。
如果你只是调用super.method()而不是mDelegate.method(),它会去;你要包装父类和实例化它。