2010-12-12 26 views
5

J'écris des classes en utilisant Generics mais je ne trouve pas de solution pour la classe SolutionsSubset et donc je l'obtiens l'erreur " S n'est pas dans sa limite ". J'ai lu les questions précédentes sur la même erreur mais je ne peux pas le résoudre pour mon cas. Quelqu'un pourrait-il m'aider à améliorer mes connaissances sur les génériques? Toute référence à un bon livre (je peux trouver dans google beaucoup d'informations mais si quelqu'un peut recommander un livre, tutoriel, etc sera la bienvenue). Bien que j'ai essayé de garder à l'esprit les règles pour poser une question, mais je s'excuser si ma question ne remplit pas ces règles.A propos d'erreur en utilisant des génériques Java: "le paramètre de type S n'est pas dans sa limite"

J'ai les classes et les interfaces suivantes:

 


public interface Subset<T extends Comparable<T>> extends Comparable<Subset<T>> 
public class MathSubset<T extends Comparable<T>> extends TreeSet<T> implements Subset<T> 

public interface Solution<T extends Comparable<T>> 

public interface Solutions<S extends Solution<?>> extends Iterable<S> 
public class SolutionsSubset<S extends Solution<?>> extends MathSubset<S> implements Solutions<S> 

 

j'ai besoin qui va Subset Comparable. Dans SolutionsSubset, la classe MathSubset stocke les objets Solution. Comment dois-je changer ces définitions pour le faire fonctionner?

Merci vous à l'avance

Répondre

1

Tout d'abord, voici l'erreur complète (qui est spécifique à MathSubset ne pas obtenir un bon paramètre): Bound mismatch: The type S is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type QifFixer.MathSubset<T>

Le problème est que MathSubset attend un <T extends Comparable<T>, mais vous donnons-lui un S extends Solution<?> - ces types n'ayant rien à voir l'un avec l'autre, car une solution n'hérite pas ou n'implémente pas Comparable<T>.

Si quoi que ce soit, vous pouvez essayer ceci:

public class SolutionsSubset<S extends Comparable<S>> extends 
    MathSubset<S> implements Solutions<Solution<S>>; 

Malheureusement, cela fonctionne toujours pas parce que MathSubset implémente Iterable, mais le fait solutions.

Une solution simple consisterait pour Solutions à ne pas étendre Iterable, mais j'ai l'impression que vous essayez d'utiliser une approche plus complexe que nécessaire. Peut-être un "has-a" au lieu de "est-un" design pourrait être plus bénéfique ici?

+0

Nous vous remercions de votre aide; J'ai finalement décidé de passer à un design "has-a". Quoi qu'il en soit, votre solution m'a aidé à mieux comprendre les génériques en Java – user539694

1

Les génériques sont quelque chose qui peut rapidement devenir incontrôlable, surtout si vous essayez d'être "tout générique" en même temps. Moins est plus. Ce qui m'aide toujours, c'est de commencer le concret (y compris la mise en œuvre), puis de remplacer lentement les paramètres génériques par un paramètre et une classe à la fois.

Quelqu'un pourrait-il m'aider à améliorer mes connaissances sur les génériques?

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

Pas un tutoriel, mais beaucoup d'informations utiles. C'est l'une de ces références que vous lisez les parties que vous pouvez comprendre, mais revenez encore et encore à l'avenir que vous gagnez plus de maîtrise et plus de cela commence à avoir un sens.

+0

Merci beaucoup. C'est un très bon web sur Java et les génériques. – user539694

6

Pour être utilisé comme argument de type dans MathSubset, SolutionsSubset de S doit extend Comparable<S>. Comme un exemple compilable:

import java.util.TreeSet; 

interface Subset<T extends Comparable<T>> 
    extends Comparable<Subset<T>> { } 

class MathSubset<T extends Comparable<T>> 
    extends TreeSet<T> 
    implements Subset<T> 
{ 
    public int compareTo(Subset<T> other) { throw new Error(); } 
} 

interface Solution<T extends Comparable<T>> { } 

interface Solutions<S extends Solution<?>> extends Iterable<S> { } 

class SolutionsSubset<S extends Solution<?> & Comparable<S>> 
    extends MathSubset<S> 
    implements Solutions<S> 
{ } 

Quelques commentaires: Ceci est un exemple très abstrait, et donc pas facile à penser. Disposer le code de sorte que vous n'avez pas besoin de faire défiler est bon.Il se passe énormément d'héritage ici, peut-être composer plutôt que, disons, étendre TreeSet. Il est difficile de faire la distinction entre les identificateurs Solutions et Solution.

+0

Merci. Votre solution était intéressante bien que je change finalement le design pour le rendre plus simple. – user539694