Question

I am working with a 3rd party framework and it turns out I need to wrap some of its objects as a delegate to one of my classes.

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
    }
}

So there is the problem. I need to delegate this method to the internal object but its protected and therefore not accessible.

Any ideas on ways to solve this particular problem? This is for Java 1.3.

Was it helpful?

Solution

Why are you constructing a separate instance of Foo? FooWrapper is already a Foo.

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

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

Edit: if you really have to have separate instance, one way (albeit slightly ugly) is to use reflection:

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: Based on your comment below, have two sub-classes of Foo, one that simply provides public versions of the protected methods, and one that has overrides all of the important methods. The first will look and act exactly like a Foo, the second can do whatever you need doing:

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 */
    }
}

OTHER TIPS

What I've done when I've been in a situation like this, and its not nice, but it works, is create a PublicFoo in the same package as Foo (but in your source), have it extend Foo, and override the protected method and make it public.

Now, FooWrapper can extend PublicFoo and do whatever you want.

Note, however, if the original jar is signed and sealed, youll need to remove the signatures before you can deploy it. (You can go into the Manifest directory in the jar, and simply delete the certificates)

Well, if it has public access to its properties (be they getters or public variables), you could create a copy constructor:

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

If the properties are objects... great, even better, because then any changes you make will show up when accessed through the original object, too! (That is, until you replace one of those objects, which you have to for immutable classes like String.)

A subclass should have access to a superclass's protected methods.

If you just call super.method() instead of mDelegate.method(), it'll go; you're both wrapping the parent class and instantiating it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top