1

我正在使用第 3 方框架,结果我需要将它的一些对象包装为我的一个类的委托。

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();
    }
}

编辑:如果你真的必须有单独的实例,一种方法(虽然有点难看)是使用反射:

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 */
    }
}
于 2009-12-07T18:03:04.463 回答
2

当我遇到这种情况时,我所做的事情并不好,但它确实有效,是在与 Foo 相同的包中(但在您的源代码中)创建一个 PublicFoo,让它扩展 Foo,并覆盖受保护的方法并将其公开。

现在,FooWrapper 可以扩展 PublicFoo 并做任何你想做的事情。

但是请注意,如果原始 jar 已签名并密封,则需要先删除签名,然后才能部署它。(您可以进入 jar 中的 Manifest 目录,只需删除证书即可)

于 2009-12-07T18:03:07.833 回答
0

好吧,如果它可以公开访问其属性(无论是 getter 还是公共变量),您可以创建一个复制构造函数:

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

如果属性是对象...很好,甚至更好,因为您所做的任何更改都会在通过原始对象访问时显示出来!(也就是说,直到您替换其中一个对象,对于像 String 这样的不可变类,您必须这样做。)

于 2009-12-07T18:33:24.013 回答
-1

子类应该可以访问超类的受保护方法。

如果你只是调用 super.method() 而不是 mDelegate.method(),它就会消失;你都在包装父类实例化它。

于 2009-12-07T18:04:57.690 回答