IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Génériques et abstraction


Sujet :

Langage Java

  1. #1
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut Génériques et abstraction
    Bonjour,

    j'ai trois classes : une classe Type, une classe Column et une classe Row.

    Un Type est bah... un type. Il doit gérer en interne un Comparable et pouvoir faire des comparaisons entre deux de ses extensions (qui peuvent être aussi bien des Type<String> que des Type<Integer> et des Type<Date>, etc).

    Une Column doit avoir un type (donc non null), mais celui-ci peut changer en cours d'exécution.

    Une Row est typiquement un mapping entre une Column typée et une valeur correspondant au type de la colonne. La valeur sera toujours bien typée, puisque lorsque le type d'une colonne change, les valeurs sont converties.

    Mon problème est que ma classe Row ne compile pas à cause des erreurs de Generics dans la méthode compareTo. Cependant, conceptuellement, les comparaisons internes faites sont toujours sur un même type (on ne comparera pas de String avec des Integer, par exemple).

    Merci à qui pourra m'aider.

    J'ai coupé mon code pour que vous puissiez voir plus précisément l'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import java.util.Comparator;
    public class Type<T extends Comparable<T>>
    		implements Comparator<T> {
    	@Override
    	public int compare (T o1, T o2) {
    		return o1 != null ? (o2 != null ? o1.compareTo(o2) : 1)
    				: (o2 != null ? -1 : 0);
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class Column {
    	private Type<?>	type;
     
    	public Column (Type<?> type) {
    		this.setType(type);
    	}
     
    	public void setType (Type<?> type) {
    		if (type == null)
    			throw new IllegalArgumentException("type is null");
    		this.type = type;
    	}
     
    	public Type<?> getType () {
    		assert type != null : "type is null";
    		return this.type;
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public class Row
    		extends HashMap<Column, ? extends Comparable>
    		implements Comparable<Row> {
    	
    	public Set<Column> getColumns() {
    		Set<Column> set = new HashSet<Column>();
    		set.put(new Column(new Type<Integer>()));
    		set.put(new Column(new Type<Float>()));
    		set.put(new Column(new Type<BigDecimal>()));
    		return set;
    	}
    	
    	@Override
    	public int compareTo (Row that) {
    		if (that != null) {
    			int cmp;
    			for (Column column : this.getColumns()) {
    				Type<?> t = column.getType();
    				
    				cmp = t.compare((Comparable) this.get(column),
    					(Comparable) that.get(column));
    				if (cmp != 0) return cmp;
    			}
    		}
    		return 0;
    	}
    }

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ton problème viens du fait que le Type<T> de chaque colonne ne peux pas être connu du compilateur, hors les généric sont justement là pour permettre au compilateur de tester ces garantie. Il en est par conséquent incapable. Ton column présente un premièr abstraction génante: on perd l'information sur le type de column en passant par Type<?>.

    Pour pus de détails sur la solution: on pourrais voir exactement l'erreur (copier/coller de la console)

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Bien sûr, la voici : (j'ai modifié mon message initial pour souligner l'erreur liée)

    The method compare(capture-of ?, capture-of ?) in the type Type<capture-of ?> is not applicable for the arguments (Comparable, Comparable)
    C'est tout à fait classique d'une erreur liée au generics.

    Mais je crois que je vais passer outre en me référant à la logique conceptuelle : je vais passer la class Type en "implements Comparable<Object>" et faire un cast dans la méthode. Ca devrait passer, non ? Même si ça m'ennuie de devoir enlever ce generics.

  4. #4
    Membre très actif Avatar de unknow0
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 452
    Par défaut
    Bonjour,

    du peu que j'en ai compris ca viendrai de la declaration du Type dans Column qui devrai etre pareil que dans la calss Type a savoir:
    Type<T extends Comparable<T>> plutot que Type<?>

    Mais je peu largement me tromper

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Bah en fait, oui, le problème vient de là. Mais je voudrais pouvoir changer le type d'une colonne, ce qui avec ton en-tête n'est pas possible.

  6. #6
    Membre très actif Avatar de unknow0
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 452
    Par défaut
    techniquement avec ce type de declaration tu peu metre n'importe quelle class tant qu'elle implement extends comparable donc tu peu quant meme changer le type d'une colone sans souci.
    enfin a mois que je me trompe

Discussions similaires

  1. classe date générique ?
    Par lili_bzh dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 07/09/2004, 10h59
  2. taille d'objet générique
    Par Heimdall dans le forum C
    Réponses: 7
    Dernier message: 01/07/2004, 18h00
  3. Réponses: 9
    Dernier message: 29/06/2004, 08h40
  4. caractère générique utilisable dans strcmp
    Par barthelv dans le forum C
    Réponses: 9
    Dernier message: 01/08/2003, 16h54
  5. Abstract VS virtual
    Par LE CHAKAL dans le forum Langage
    Réponses: 2
    Dernier message: 29/08/2002, 17h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo