Pergunta

Eu estou trabalhando com um quadro 3o partido e não é que eu preciso para embrulhar alguns de seus objetos como um delegado para uma das minhas aulas.

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

Portanto, não é o problema. Eu preciso delegar esse método para o objeto interno, mas a sua protegida e, portanto, não acessível.

Todas as ideias sobre formas de resolver este problema em particular? Isto é para Java 1.3.

Foi útil?

Solução

Por que você está construindo uma instância separada do Foo? FooWrapper já é uma Foo.

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

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

Editar : se você realmente tem que ter instância separada, de uma forma (embora um pouco feio) é usar a reflexão:

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: Com base no seu comentário abaixo, tem duas subclasses de Foo, que simplesmente fornece versões públicas dos métodos protegidos, e que tem substitui todos os métodos importantes. O primeiro vai olhar e agir exatamente como um Foo, o segundo pode fazer o que você precisa fazer:

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

Outras dicas

O que eu fiz quando eu estive em uma situação como esta, e não é agradável, mas funciona, é criar um PublicFoo no mesmo pacote como Foo (mas em sua fonte), tê-lo estender Foo, e substituir o método protegido e torná-la pública.

Agora, FooWrapper pode estender PublicFoo e fazer o que quiser.

Note, no entanto, se o frasco original assinado e selado, você precisará remover as assinaturas antes de implantá-lo. (Você pode ir para o diretório manifesto na jarra, e simplesmente excluir os certificados)

Bem, se ele tiver acesso do público às suas propriedades (sejam eles getters ou variáveis ??públicas), você pode criar um construtor de cópia:

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

Se as propriedades são objetos ... excelente, ainda melhor, porque então todas as alterações feitas aparecerão quando acessado através do objeto original, também! (Isto é, até você substituir um desses objetos, que você tem que para classes imutáveis ??como cadeia.)

Uma subclasse devem ter acesso a um métodos protegidos da superclasse.

Se você apenas chamar super.method () em vez de mDelegate.method (), ele vai; você está tanto embrulho a classe pai e instanciar-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top