Cloneable
helloworld95
-
KX Messages postés 19031 Statut Modérateur -
KX Messages postés 19031 Statut Modérateur -
Bonjour,
Toujours dans ma classe Client, j'aimerai éviter quelle référence toujours la même commande.
Si j'ajoute un article dans les
Exemple:
J'ai donc essayer avec un clone mais ce ne fonctionne pas.
Dans commande :
Dans Client :
Comment faire dans ce cas ?
Toujours dans ma classe Client, j'aimerai éviter quelle référence toujours la même commande.
Si j'ajoute un article dans les
Exemple:
public class TestAttribut {
public static void main(String[] args) {
Client client = new Client("Robert", "Michel");
Commande commande = new Commande(2, LocalDateTime.now());
commande.ajouterArticle(new Article(1, "Nespresso", 5));
client.enregistrerCommande(commande);
System.out.println(client.getCommande());
//ajouter un article ne doit pas modifier la commande du client
commande.ajouterArticle(new Article(2, "Cappuccino", 7.50));
System.out.println(client.getCommande());
}
}
J'ai donc essayer avec un clone mais ce ne fonctionne pas.
Dans commande :
@Override
protected Commande clone() throws CloneNotSupportedException{
return (Commande) super.clone();
}
Dans Client :
public void enregistrerCommande(Commande commande) throws CloneNotSupportedException{
this.commande = commande.clone();
}
Comment faire dans ce cas ?
2 réponses
Le code n'est pas complet (code de commande notamment).
La classe Commande implémente bien l'interface Cloneable ?
Une erreur lors de la compilation ou de l'exécution ?
La classe Commande implémente bien l'interface Cloneable ?
Une erreur lors de la compilation ou de l'exécution ?
Bonjour,
Ton code est bon, c'est le main() qui t'induit en erreur.
Tu as mis le clone() dans la méthode enregistrerCommande() mais tu ne l'appelle pas...
Avec ce main, c'est bon, ton clone() est bien effectif :
Ton code est bon, c'est le main() qui t'induit en erreur.
Tu as mis le clone() dans la méthode enregistrerCommande() mais tu ne l'appelle pas...
Avec ce main, c'est bon, ton clone() est bien effectif :
Commande c1 = client.getCommande(); client.enregistrerCommande(commande); Commande c2 = client.getCommande(); System.out.println(c1 == c2); // false
Je n'ai pas très bien compris le principe...
Mais dans le cas ci dessous par exemple, il ajoute quand même les articles dans la commande du client sans passer par enregistrerCommande() mais directement par l'objet Commande. Est-ce possible de l'eviter ?
Mais dans le cas ci dessous par exemple, il ajoute quand même les articles dans la commande du client sans passer par enregistrerCommande() mais directement par l'objet Commande. Est-ce possible de l'eviter ?
Commande c2 = client.getCommande(); System.out.println(c2); commande.ajouterArticle(new Article(3, "Latte", 3.50)); Commande c3 = client.getCommande(); System.out.println(c3); // output les 3 articles de la liste
Déjà, pour moi ce que tu fait n'as pas trop de sens, tu ne peux pas avoir une commande l'enregistrer, puis la modifier à nouveau. Si la commande est enregistrée c'est fini, tu ne devrais ni pouvoir ajouter d'articles, ni pouvoir enregistrer à nouveau une commande déjà enregistrée.
Si on était sur un site marchand, tu aurais deux notions biens distinctes, le "panier" que tu remplis d'articles au fur et à mesure et la commande que tu obtiens une fois le panier validé (et le paiement accepté...)
Ce qui aurait plus du sens, en programmation objet, ce serait.
Remarque : cela fait plusieurs années que je programme en Java et jamais je n'ai réellement eu besoin de clone().
Il y a d'autres mécanismes bien meilleurs pour faire les choses proprement. Voir Java Practices → avoid clone
Si on était sur un site marchand, tu aurais deux notions biens distinctes, le "panier" que tu remplis d'articles au fur et à mesure et la commande que tu obtiens une fois le panier validé (et le paiement accepté...)
Ce qui aurait plus du sens, en programmation objet, ce serait.
Panier panier = new Panier(); panier.ajouterArticle(article1, quantité1); panier.ajouterArticle(article2, quantité2); Commande commande = panier.enregistrerCommande();
Remarque : cela fait plusieurs années que je programme en Java et jamais je n'ai réellement eu besoin de clone().
Il y a d'autres mécanismes bien meilleurs pour faire les choses proprement. Voir Java Practices → avoid clone
Tu pourrais utiliser Collections.unmodifiableList pour protéger ta liste.
public class Commande {
private final List<Article> listeArticles;
public List<Article> getArticles() {
return Collections.unmodifiableList(listeArticles);
}
}
List<Article> articles = commande.getArticles(); articles.add(new Article(3, "Latte", 3.50)); // UnsupportedOperationException
public class Commande implements Cloneable { private int numero; private LocalDateTime date; List<Article> listeArticles; public Commande(int numero, LocalDateTime date) { this.numero = numero; listeArticles = new ArrayList<>(); } public boolean ajouterArticle(Article article) { if (listeArticles.contains(article)) return false; listeArticles.add(article); return true; } public int getNumero() { return numero; } public LocalDateTime getDate() { return date; } @Override public String toString() { return this.numero + " " + listeArticles.toString(); } @Override protected Commande clone() throws CloneNotSupportedException{ return (Commande) super.clone(); } }