Question

Je travaille avec un cadre 3ème partie et il se trouve que je dois envelopper certains de ses objets en tant que délégué à l'une de mes 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
    }
}

Alors il y a le problème. Je dois déléguer cette méthode à l'objet interne mais son protégé et donc pas accessible.

Toutes les idées sur les moyens de résoudre ce problème particulier? Ceci est pour Java 1.3.

Était-ce utile?

La solution

Pourquoi vous construisez une instance distincte de Foo? FooWrapper est déjà un Foo.

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

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

Modifier : si vous avez vraiment avoir instance séparée, d'une manière (quoique légèrement laid) est d'utiliser la réflexion:

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: En fonction de votre commentaire ci-dessous, ont deux sous-classes de Foo, qui fournit simplement des versions publiques des méthodes protégées, et qui a des Remplace toutes les méthodes importantes. Le premier regardera et agir exactement comme un Foo, le second peut faire ce que vous devez faire:

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

Autres conseils

Qu'est-ce que je l'ai fait quand je suis dans une situation comme ça, et ce ne est pas agréable, mais il fonctionne, est de créer un PublicFoo dans le même paquet que Foo (mais dans votre source), faites-le prolonger Foo, et remplacer la méthode protégée et le rendre public.

Maintenant, FooWrapper peut étendre PublicFoo et faire ce que vous voulez.

Notez, cependant, si le pot d'origine est signé et scellé, vous aurez besoin d'enlever les signatures avant de pouvoir le déployer. (Vous pouvez aller dans le répertoire Manifest dans le pot, et simplement supprimer les certificats)

Eh bien, si elle a l'accès du public à ses propriétés (qu'ils soient ou getters variables publiques), vous pouvez créer un constructeur de copie:

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

Si les propriétés sont des objets ... grand, encore mieux, parce que toutes les modifications apportées sera affiché quand on y accède par l'objet original aussi! (C'est, jusqu'à ce que vous remplacez l'un de ces objets, que vous devez pour les classes immuables comme String.)

Une sous-classe devrait avoir accès à un les méthodes protégées superclasse.

Si vous appelez juste super.method () au lieu de mDelegate.method (), ça va aller; vous êtes tous les deux enroulant la classe parente et instancier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top