J'essaie d'utiliser des génériques pour prendre en charge une structure configurable de délégation d'objets (décorateurs, emballages). Je veux construire une chaîne de délégateurs qui implémente une interface cible ainsi qu'une interface de délégatrice générique.
J'ai ce contour: p> mais, en essayant d'instancier La variable code> chaîne code>, compilateur se plaint: p> MisMatch lié: Le type test.foodelegator n'est pas un substitut valide pour le paramètre limité J'admets que les génériques sont comme Magic pour moi, Mais je peux en quelque sorte reconnaître que Foodélégator n'est pas une foo que s'étend em> délégatrice étant donné ce que je veux accomplir, est là tout ce que je peux faire wrt Génériques pour le réparer, ou je suis juste mieux d'oublier à ce sujet? P> p>
test.delegatorchain
3 Réponses :
Que devrait fonctionner à la place, si Troisième alternative, qui devrait également fonctionner: P> Foodélégator implémente le délégateur FOO implémente délégateur t implémente délégateur DelegatorChain<T extends Delegator<F>, F> chain; ...
On dirait que c'est ce que vous essayez de faire.
static interface Delegator<T> {
}
static class DelegatorChain<T extends Delegator<C>, C> {
}
static interface Foo {
}
static class FooDelegator implements Delegator<Foo>, Foo {
}
public static void main(String[] args) {
DelegatorChain<FooDelegator, Foo> chain = new DelegatorChain<FooDelegator, Foo>();
}
Ce n'est pas tout à fait la même chose, plutôt que c'est correct. Il n'est que redondant, car le C doit être déclaré comme un type lorsque vous l'utilisez dans une autre déclaration de type générique (T).
+1 Je crois que cela atteint ce que l'asservis spécifié, il spécifie une chaîne de délégateurs qui implémente une interface cible C code>: foo code>, ainsi qu'une interface de délégatrice générique T code>: délégateur
Dans votre définition, un délégateur est un délégateur de lui-même (comme le comparable est par exemple), mais il semble que l'intention est que le délégateur est un délégateur d'une super catégorie. Heureusement, les génériques ont une façon d'exprimer ceci:
// Not recommended, but will allow compile:
static class FooDelegator implements Delegator<FooDelegator>, Foo {}
// However, this also compiles :(
static class FooDelegator implements Delegator<FooDelegator>, Bar {}
D'accord, la deuxième solution est plus propre, tant que vous pouvez saisir le super concept ;-)
+1 Je copie mon commentaire depuis un autre message, car la deuxième méthode réalise ce que l'Asker a spécifié. Il spécifie une chaîne de délégatrice code> S qui implémente une interface cible ? Code>: foo code>, ainsi qu'un délégateur générique code> Interface t code>: délégateur > code>. Je crois que la première méthode le fait de manière inappropriée.
D'accord - je ne l'ai compris qu'après que j'ai posté. J'ai édité la réponse pour refléter cela.
Pourquoi le type générique de votre délégatrice doit-il étendre le délégateur? Votre classe de délégatrice fournit les informations de type. requis par le délégateur et le Foodélégator fournit la mise en œuvre du délégateur.
Il ne compile pas car
foo code> n'est pas undélégateur code>. Nabealimemon.com/blog/2011/01/fself-bound -Les types génériquesOui, les types ne correspondent pas. Le type générique dans la délégatrice est un "foodélégator", mais le type générique requis dans le délégateur est "FOO". Vous aurez besoin du paramètre de type générique supplémentaire que j'ai fourni dans ma réponse pour le faire fonctionner car vous avez l'intention de croire. ou juste partir de la contrainte.
Ma question à vous, à partir d'un point de vue de design, la délégatrice doit-elle connaître à la fois le délégateur qu'il contient et l'interface du délégateur implémente? La réponse à cela pourrait avoir une incidence sur laquelle des réponses déjà soumises correspond à vos besoins mieux.
@ Ty1824, pensant toujours ... Oui, il a besoin de connaître les deux. En fin de compte, toute la structure devrait pouvoir agir comme une foo.
Si tel est le cas, vous voudrez peut-être essayer la solution à deux paramètres par Scarcher2.
Type, c> code>. Dans ce cas, vous indiquez explicitement l'interface ( C code>), plutôt que implicitement (s'appuyant sur le Wildcard? Code> dans le? Super t code> ). Cependant, les deux solutions correspondent à la spécification, de sorte que tout dépend de ce dont vous aurez besoin et comment les données vont couler une fois que tout est créé.