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éricité et constructeurs


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut Généricité et constructeurs
    Bonjour à toutes et à tous

    Je patauge dans la création de classes avec généricité, notamment pour créer des constructeurs. Voici un exemple. Je crée une classe "Animal" qui a comme sous-classe "Chien". Je pourrais de même créer la classe "Chat", etc. Jusque là pas de problème. Et j'attaque la généricité en créant une classe "Couple" qui a comme variables (génériques) un male et une femelle. Je tente plusieurs écritures de constructeurs et... pas une ne se compile ! Voici l'objet du délit.

    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
    28
    29
    30
    31
    32
    33
    34
    35
    package testGenericite;
     
    class Animal {
        public String espece ;
        public Animal (String espece) {this.espece = espece ;}
        public Animal (Animal parent) {this.espece = parent.espece ;}
    }
    class Chien extends Animal {
        public Chien () {super ("Chien") ;}
        public Chien (Chien parent) {super (parent) ;}
    }
     
    public class Couple <TypeAnimal extends Animal> {
        TypeAnimal male, femelle ;
        public Couple (String espece) {
            male = new Animal (espece) ;
            femelle = new Animal (espece) ;
        }
        public Couple (Animal male, Animal femelle) {
            this.male = male ;
            this.femelle = femelle ;
        }
        public Couple (Chien male, Chien femelle) {
            this.male = male ;
            this.femelle = femelle ;
        }
        public Couple (TypeAnimal male, TypeAnimal femelle) {
            this.male = male ;
            this.femelle = femelle ;
        }
        public Couple (Couple parents) { // tant pis pour la consangüinité
            male = new Animal (parents.male.espece) ;
            femelle = new Animal (parents.femelle.espece) ;
        } 
    }
    Alors, j'ai tout faux... Il y a une notion fondamentale qui m'échappe ?

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Hello,

    celui-ci est parfait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Couple (TypeAnimal male, TypeAnimal femelle) {
      this.male = male ;
      this.femelle = femelle ;
    }
    Mais il ne compile pas à cause des autres. Si tu gardes du code mauvais, il a ses chances de planter d'autres parties de code qui pourtant est bon. Ne garde pas de code mauvais. Quand tu vois que ça marche pas, enlève.

    Pourquoi c'est ce constructeur-là qui est le bon, ça devrait être évident.
    Les variables membre male et femelle de ta classe, sont de type TypeAnimal. Quel est le seul constructeur qui propose de leur donner des valeurs de type TypeAnimal ? Celui-ci. Normal que ce soit le seul bon.

    Pourquoi les autres constructeurs l'empêchent de compiler, en fait c'est seulement celui-ci qui gêne : public Couple (Animal male, Animal femelle) {.
    C'est un peu compliqué, raison pour laquelle il est plus simple de juste pas laisser du mauvais code, pour pas empêcher le bon code de marcher.
    Mais bon, la raison c'est que les génériques en Java, c'est un truc pour aider pendant la compilation. Ça te sert à vérifier que tu respectes bien les règles de typage de tes objets, pendant que tu programmes. Et des vérifications de ce genre, ça se fait à la compilation.
    A l'exécution par contre, les génériques n'existent plus. A la place ils sont remplacés par des classes concrètes, les plus précises possibles mais pas génériques.
    Ce qui veut dire qu'à l'exécution, ton constructeur public Couple (TypeAnimal male, TypeAnimal femelle) est remplacé par public Couple (Animal male, Animal femelle). Or comme tu en avais déjà fait un comme ça, ce remplacement n'est pas possible. Le compilateur le refuse donc.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    OK vu, merci. J'en conclus que la déclaration "TypeAnimal" est utilisée comme une "macro" dans une première phase de compilation et que, une fois remplacées textuellement les chaines "Animal" sont vues comme des classes distinctes, donc erreurs de compilation, y compris s'il y a deux constructeurs identiques après macro-remplacement. Je m'aperçois en conséquence que je peux faire un "cast" sur "TypeAnimal", donc les constructeurs suivants se compilent et fonctionnent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        public Couple (String espece) {
            male = (TypeAnimal) (new Animal (espece)) ;
            femelle = (TypeAnimal) new Animal (espece) ;
        }
        public Couple (Couple parents) { // tant pis pour la consangüinité
            male = (TypeAnimal) (new Animal (parents.male.espece)) ;
            femelle = (TypeAnimal) (new Animal (parents.femelle.espece)) ;
        }
    Merci encore. Je passe à l'étape suivante, déclarer des collections d'animaux génériques et les utiliser dans une boucle for (TypeAnimal a : liste) {;} Je vais appliquer ce principe et voir si je m'en sors.

Discussions similaires

  1. Réponses: 78
    Dernier message: 27/08/2009, 20h29
  2. [VB6]Déclaration d'un Constructeur Spécialisé
    Par TagadaTsoin dans le forum VB 6 et antérieur
    Réponses: 21
    Dernier message: 26/05/2004, 15h09
  3. [Constructeur]Pb avec la surcharge d un constructeur
    Par cmoulin dans le forum Langage
    Réponses: 3
    Dernier message: 26/04/2004, 10h29
  4. Capture d'exception dans un constructeur
    Par declencher dans le forum Composants VCL
    Réponses: 8
    Dernier message: 03/02/2004, 13h52
  5. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 20h02

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