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 :

[Conception] Deux constructeurs pour une même classe, l'un appelant l'autre


Sujet :

Langage Java

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut [Conception] Deux constructeurs pour une même classe, l'un appelant l'autre
    Bonjour,

    Je suis en train de créer une application et je suis confronté au problème (peut être un faux problème) suivant :
    J'ai une classe Element qui posséde 3 attributs (nom, type, path).
    Lors de l'instanciation de cette classe, je peux avoir soit 1, soit 2, soit 3 des attributs transmis.
    J'ai donc les constructeurs suivants :
    Element(String nom, String path, char type)
    Element(String path, char type)
    Element(String nom, String path)
    Element(String path)

    Lorque ma classe est instanciée par le constructeur Element(String nom, String path), je determine le type dans le constructeur et ensuite, je souhaiterais instancier la classe en faisant appel au constructeur Element(String nom, String path, char type) qui valorise les attributs et effectue des contrôle.

    Mais lorsque je mets en pratique, j'ai le message suivant :
    "Constructor call must be the first statement in a constructor"

    Lorsque l'objet est instancier par le constructeur Element (String nom, String path) je ne connais pas le type, je dois donc exécuter du code pour determiner le type en fonction de nom et path mais alors je ne peux plus finir l'instanciation en appelant mon constructeur Element(String nom, String path, char type).
    D'où la question suivante :
    Dois-je implémenter mon code de valorisation des attributs dans tous mes constructeurs ou mon problème vient-il d'une erreur de conception ?

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import java.io.File;
     
    public class Element {
    	private String nom;
    	private String path;
    	private char type;
     
    	public Element(String nom, String path, char type) {
    		this.setNom(nom);
    		this.setPath(path);
    		this.setType(type);
    	}
    	public Element(String nom, String path) {
    		File file;
     
    		file = new File(path);
    		if(file.isDirectory()) {
    			this(nom, path, 'D');
    		}
    	}
    	public Element(String path, char type) {
    	}
    	public Element(String path) {
    	}
     
    	private String getNom() {
    		return this.nom;
    	}
    	private String getPath() {
    		return this.path;
    	}
    	private char getType() {
    		return this.type;
    	}
    	private void setNom(String nom) {
    		this.nom = nom;
    	}
    	private void setPath(String path) {
    		this.path = path;
    	}
    	private void setType(char type) {
    		this.type = type;
    	}
    }

  2. #2
    Membre éclairé Avatar de g_rare
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 608
    Points : 683
    Points
    683
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public Element(String nom, String path) {
    this(nom,path,new File(path).isDirectory() ? 'D' : '\u0000');
    }
    Par contre voir du côté des Design Pattern "Factory" ou "Builder".


  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Un constructeur commence obligatoirement soit par un appel à un autre constructeur (donc this(...)), soit par un appel au constructeur parent (donc super(...)).

    Si aucune de ces deux instructions n'est utilisées, c'est super() qui est utilisé implicitement, donc ton code est équivalent à celui-ci :
    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
    	public Element(String nom, String path, char type) {
    		super();
    		this.setNom(nom);
    		this.setPath(path);
    		this.setType(type);
    	}
    	public Element(String nom, String path) {
    		super();
    		File file;
     
    		file = new File(path);
    		if(file.isDirectory()) {
    			this(nom, path, 'D');
    		}
    	}
    Si c'était autorisé, dans le second constructeur tu appellerais deux fois le constructeur de la classe parente...

    L'appel à this() doit donc obligatoirement correspondre à la première instruction du constructeur.

    Dans ton cas tu peux remédier cela en utilisant la structure conditionnelle ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public Element(String nom, String path, char type) {
    		this.setNom(nom);
    		this.setPath(path);
    		this.setType(type);
    	}
    	public Element(String nom, String path) {
    		this(nom, path, new File(path).isDirectory() ? 'D' : 'F' );
    	}
    Mais
    • Cela ne fonctionne pas si tu as un code plus complexe...
    • Ce n'est pas forcément très lisible



    Une solution alternative que je te conseillerais serais d'utiliser une méthode private pour initialiser ton composant, par exemple :
    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
    	private void init(String nom, String path, char type) {
    		this.setNom(nom);
    		this.setPath(path);
    		this.setType(type);
    	}
     
    	public Element(String nom, String path, char type) {
    		init(nom, path, type);
    	}
    	public Element(String nom, String path) {
    		File file = new File(path);
    		if(file.isDirectory()) {
    			init(nom, path, 'D');
    		} else {
    			init( ... );
    		}
    	}
    a++

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par adiGuba
    Une solution alternative que je te conseillerais serais d'utiliser une méthode private pour initialiser ton composant, par exemple :
    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
    	private void init(String nom, String path, char type) {
    		this.setNom(nom);
    		this.setPath(path);
    		this.setType(type);
    	}
     
    	public Element(String nom, String path, char type) {
    		init(nom, path, type);
    	}
    	public Element(String nom, String path) {
    		File file = new File(path);
    		if(file.isDirectory()) {
    			init(nom, path, 'D');
    		} else {
    			init( ... );
    		}
    	}
    a++
    merci pour vos réponses, je pense que je vais retenir la solution alternative d'adiGuba. Maintenant simplement pour ma culture personnelle, y'a t'il des contre-indications d'utilisation ?

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bigben99
    Maintenant simplement pour ma culture personnelle, y'a t'il des contre-indications d'utilisation ?
    Comme toutes les méthodes appelé dans un constructeur, elle devrait être soit private soit final afin d'éviter de possible problème lors de la redéfinition dans une classe fille...

    Sinon je ne vois pas vraiment de contre indication...

    a++

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par adiGuba
    Comme toutes les méthodes appelé dans un constructeur, elle devrait être soit private soit final afin d'éviter de possible problème lors de la redéfinition dans une classe fille...

    Sinon je ne vois pas vraiment de contre indication...

    a++
    Ok, merci pour les précisions

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/04/2013, 12h07
  2. Deux jars pour une même module EJB
    Par krum dans le forum Wildfly/JBoss
    Réponses: 0
    Dernier message: 09/11/2009, 15h15
  3. Probleme constructeurs d'une même classe
    Par LinuxUser dans le forum Langage
    Réponses: 4
    Dernier message: 06/06/2007, 14h58
  4. [POO] Deux constructeurs pour une même classe
    Par amika dans le forum Langage
    Réponses: 4
    Dernier message: 16/12/2006, 16h31
  5. Réponses: 15
    Dernier message: 19/06/2006, 19h25

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