Pregunta

Estoy trabajando con un marco tercera parte y resulta que necesito para envolver algunos de sus objetos como delegado a una de mis clases.

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

Por lo tanto, existe el problema. Necesito delegar este método al objeto interno pero su protegido y por lo tanto no es accesible.

Cualquier ideas sobre la manera de resolver este problema en particular? Esto es para Java 1.3.

¿Fue útil?

Solución

¿Por qué la construcción de una instancia independiente de Foo? FooWrapper ya es un Foo.

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

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

Editar : si realmente tiene que tener instancia independiente, de una manera (aunque un poco feo) es utilizar la reflexión:

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: Basado en su comentario a continuación, tiene dos subclases de Foo, uno que simplemente ofrece versiones públicas de los métodos protegidos, y que tiene todas las anulaciones de los métodos importantes. El primero de ellos se ven y actúan exactamente igual que un Foo, el segundo puede hacer lo que hay que hacer:

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

Otros consejos

Lo que he hecho cuando he estado en una situación como esta, y no es agradable, pero funciona, es crear un PublicFoo en el mismo paquete que Foo (pero en su origen), haga que se extienden Foo, y reemplazar el método protegido y hacerlo público.

Ahora, FooWrapper puede extender PublicFoo y hacer lo que quiera.

Tenga en cuenta, sin embargo, si el frasco original firmado y sellado, usted necesitará para eliminar las firmas antes de poder desplegarlo. (Usted puede entrar en el directorio de manifiesto en el frasco, y simplemente eliminar los certificados)

Bueno, si tiene acceso público a sus propiedades (ya se trate de captadores o variables públicas), se podría crear un constructor de copia:

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

Si las propiedades son objetos ... muy bien, incluso mejor, porque entonces cualquier cambio que realice se mostrará cuando se accede a través del objeto original, también! (Es decir, hasta que se sustituye uno de esos objetos, que usted tiene que para las clases inmutables como cadena.)

Una subclase debe tener acceso a un métodos protegidas de superclase.

Si llamas a super.method () en lugar de mDelegate.method (), que va a ir; los dos están envolviendo la clase padre y crear instancias de ella.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top