Aller au contenu

Java : supprimer une variable


bibisousnours

Messages recommandés

:keskidit: coucou tout le monde

Je début en java, et j'ai un projet à faire. Je n'ai eu qu'un cours pour l'instant, donc on nous a appris à créer une classe, une méthode, instancier un objet de cette classe et lui appliquer une méthode. (ca c'est que je sais, bref, la toute base)

Mon projet est plus consistant, donc, je me suis mis dessus avant d'avoir les cours (de tte facon, m'est avis que les cours arriverons à chaque fois après qu'on en ai eu besoin, puisque les séances de prog sont avant le cours dans la semaine).

Pour faire bref, je dois recevoir des données d'un serveur (local, déjà créé par le prof, il tourne sur ma machine) et les traiter. Ces données sont des formes (cercle, carré, rectangle, ...) avec leurs coordonnées. Une fois recues, je dois afficher les formes, les une au dessus des autres. Arrivé à la 11eme, je dois supprimer la première et afficher la 11eme, sans que les autres formes n'aient disparue. (tampon double buffer à utiliser, mais je devrais avoir un cours là dessus. ma question n'est pas là).

Bref, je dois constament avoir 10 variables, chacune faisant référence à une forme, pour que je puisse les rappeler.

Je compte faire une classe par forme. (carré, rectangle, cercle, oval et ligne). Mon probleme est qu'une fois les 10 premieres formes crées (par exemple Carree forme1=new Carree(x1,x2,y1,y2); ) je ne sais pas comment "supprimer la premiere instanciation (donc celle de forme1) afin de la recréer pour un autre type de forme

ex:

Rectangle forme1= new Rectangle(x1,x2,y1,y2);

sachant que forme1 était à la base un carré....

y'a t il une "fonction" permettant de supprimer l'instance forme1 afin de la réinstancier par la suite à une autre classe? :craint:

Sinon, comment faire pour créer un nom d'instance avec un paramètre "i" variable, genre:

for (i=1;i<10;i++) {

Forme forme&(String i) = new Forme();

}

me donnerait 10 instances de la classe Forme, appelées forme1, forme2,...forme10 ?

Merci! :keskidit:

Lien vers le commentaire
Partager sur d’autres sites

Sinon, comment faire pour créer un nom d'instance avec un paramètre "i" variable, genre:

for (i=1;i<10;i++) {

Forme forme&(String i) = new Forme();

}

me donnerait 10 instances de la classe Forme, appelées forme1, forme2,...forme10 ?

Si tu veux gérer une variable i à la construction,

il faut que tu gères ça dans le constructeur de ta classe :

un petit exemple :

(le code n'est sans doute pas correct à 100%, mais ça peut t'aider pour commencer)

class Forme {
int VariableInterne;

Forme ()
{
// Constructeur sans paramètres
}

Forme (int i)
{
// Constructeur avec paramètres
VariableInterne = i
}

~Forme ()
{
// Destructeur
}
}

Lien vers le commentaire
Partager sur d’autres sites

----------------------------

Sinon, comment faire pour créer un nom d'instance avec un paramètre "i" variable, genre:

for (i=1;i<10;i++) {

Forme forme&(String i) = new Forme();

}

------------------------

possible en C/C++ avec les macros (et encore ce sera très limité par rapport à ce que tu veux faire), impossible en Java. Ce que tu essaies de faire c'est de créer dynamiquement des symboles, ça ne peut pas fonctionner.

-----------------------------------------

y'a t il une "fonction" permettant de supprimer l'instance forme1 afin de la réinstancier par la suite à une autre classe?

------------------------------------------

Pour ce qui est de détruire une précédente instance, il suffit de la dé-référencer. Dès que plus aucune référence ne pointe sur une instance on dit qu'elle est déréférencée, cad qu'elle n'est plus utilisée nulle part dans ton programme, donc elle passe dans le garbage collector.

example :

1: ClasseA instance = new ClasseA(); //je crée une instance

2: instance = new ClasseA(); // Je crée de nouveau une nouvelle instance

En 2: la référence "instance" ne pointe plus sur l'instance générée en 1:, car la référence a pris pour valeur l'adresse (en Java on ne manipule pas directement des adresses lors du codage, on parle alors de référence car il n'y a pas de notion d'arithmétique des pointeurs mais la notion de référence n'est que symbolique, derrière ce sont des adresses) de la nouvelle instance générée en 2: .

Si l'instance crée en 1: n'est référencée nulle part ailleurs dans le programme elle sera éliminée par le garbage collector.

En Java tu ne t'occupe pas directement de la destruction des objets, tu ne fais que les déréférencer, après c'est le garbage collector en runtime qui fait le boulot.

Lien vers le commentaire
Partager sur d’autres sites

En Java tu ne t'occupe pas directement de la destruction des objets, tu ne fais que les déréférencer, après c'est le garbage collector en runtime qui fait le boulot.

en fait, en Java, tu n'as pas à t'occuper du destructeur, car le GC fait le boulot

(Meme, s'il n'est pas toujours bien fait...)

...mais dans certains cas, on est "obligé" de coder aussi le destructeur (meme si ce sont des cas rares)

Pour info: on peut aussi forcer l'exécution du GC (car il est exécuté quand le CPU est peu sollicité)

Lien vers le commentaire
Partager sur d’autres sites

Pour info: on peut aussi forcer l'exécution du GC (car il est exécuté quand le CPU est peu sollicité)

En fait il y a deux phases dans le garbage collector.

La constitution d'une liste d'instances non référencées : celà se fait effectivement lorsque du CPU est dispo.

La finalization des objets avec libération des emplacements en mémoire : elle n'est en fait exécutée QUE lorsque la mémoire disponible devient limite à savoir proche à je ne sais combien de % de la taille maximale allouée dans le heap. En fait cette phase n'est presque jamais appelée.

C'est pourquoi pour libérer réellement la mémoire il est parfois nécessaire de forcer la seconde phase du GC ; et c'est également aussi pourquoi lorsque l'on traque les processus Java on a l'impression que la JVM consomme toujours énormément de mémoire et que l'on va en manquer (en fait ce n'est pas grave car en cas de réel besoin le GC libère de manière effective la mémoire, on observe en général à ce moment une augmentation de la charge CPU et un ralentissement de la JVM, c'est un processus très consommateur de ressources voilà pourquoi il n'est que rarement exécuté).

Lien vers le commentaire
Partager sur d’autres sites

En reusmé :

Le truc que notre ami veut faire est :

Carre forme = new Carre(...);
...
Rectangle forme = new Rectangle(...);

Chose impossible dans la plupart des langages.

Comme l'a dit mogwai93, il faut creer une forme generale dont carre, rectangle, ... vont heriter.

public class Forme {
...
}

public class Carre extends Forme {
...
}

en utilisation on a :

Forme forme = new Carre (...);
...
forme = new Rectangle (...);

Comme certains l'ont dit, il n'est pas la peine de supprimer "forme" puisque le garbage collector fait ce boulot.

En ce qui concerne l'utilisation d'une variable a nom variable comme forme1, forme2, ... , il est impossible en Java de le faire. (Le langage qui gere ca bien et defacon souple est l'action script de flash MX). Tu peux soit utiliser un tableau soit utiliser une collection de type arraylist http://www.laltruiste.com/document.php?url..._arraylist.html.

Lien vers le commentaire
Partager sur d’autres sites

:incline: Merci pour ces réponses

Je ne comptais pas faire de classe Forme générale parce qu'on nous a "demandé" de faire des calsses Carre, rectangle, etc...

Effectivement, une classe unique semblerait me poser moins de problème. (enfin, dans ma tête c'est plus clair avec une classe unique. Meme sans classe en fait, mais bon, il faut que ca soit orienté classe et objet, donc, je m'y applique, ca ne peut que me faire du bien pour comprendre le principe des classe).

Donc, d'après ce que j'ai compris de vos posts, pour réutiliser une variable form1 déjà instancer de cette facon:

Carre forme1= new Carre();

je dois ecrire:

forme1=new Carre(); //ce qui a pour effet de le faire pointer vers rien et le GC va faire le ménage

puis

Rectangle forme1=new Rectangle(); //pour instancer de nouveau avec un nouveau constructeur

Pourtant, j'utilise Eclipse pour programmer, et lorsque je faisais:

Carre forme1=new Carre();

puis

Rectangle forme1=new Rectangle();

(ces deux lignes de code étant dans la même classe mais pas forcément dans la même méthode)

Eclipse soulignait forme1, affichant une erreur car forme1 était déjà instancer.

Suffit-il alors de rajouter la ligne:

forme1=new Carre();

entre les deux afin de faire pointer forme1 vers rien?

Faut il alors attendre que le GC soit passé pour pouvoir utiliser de nouveau le nom de la variable forme1? Comment peut-on alors être sur que le GC est passé, alors que le prof nous a expliqué qu'on ne le savait pas vraiment et que même en lui demandant explicitement de passer, il le faisait un peu qd il le voulait ? (il avait pris pour exemple une mere demandant à son enfant de ranger sa chambre. Ce dernier faisant "oui oui", sans toutefois le faire immédiatement)

Merci pour vos réponses très completes, c'est vraiment sympa de prendre ce temps :mdr:

Lien vers le commentaire
Partager sur d’autres sites

Comme l'a dit mogwai93, il faut creer une forme generale dont carre, rectangle, ... vont heriter.

public class Forme {
...
}

public class Carre extends Forme {
...
}

en utilisation on a :

Forme forme = new Carre (...);
...
forme = new Rectangle (...);

Comme certains l'ont dit, il n'est pas la peine de supprimer "forme" puisque le garbage collector fait ce boulot.

Je vais tenter cette méthode qui me parle un peu quand je la lis. Ca me parait correcte, du haut de mes quelques notions de base :incline:

Je ne savais pas qu'on pouvait dire que forme1 était une Forme dont le constructeur n'était pas Forme() mais Carre() ou Rectangle()...

Ca a bien l'air d'etre la solution à mon problème.

Merci beaucoup :mdr:

En plus, ca me fait comprendre un peu mieu les classes héritées :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Je vais tenter cette méthode qui me parle un peu quand je la lis. Ca me parait correcte, du haut de mes quelques notions de base :byebye:

Je ne savais pas qu'on pouvait dire que forme1 était une Forme dont le constructeur n'était pas Forme() mais Carre() ou Rectangle()...

Ca a bien l'air d'etre la solution à mon problème.

Merci beaucoup :chinois:

En plus, ca me fait comprendre un peu mieu les classes héritées :transpi:

Quand tu fais :

Forme forme = new Carre (...);

Ca appelle le constructeur de Carre, mais aussi celui de Forme

si tu l'appelles ( avec Super ).

La méthode Super permet d'appeler les méthodes/champs de la classe parente.

D'ailleurs, si tu débutes, tu peux mettre des

System.out.println("...");

dans les méthodes pour savoir ce qu'il fait.

Enfin, Java n'est pas plus compliqué que C/C++ (je vais me faire taper dessus :pleure: )

Ca te permet de "comprendre" la programmation objet vu que Java c'est surtout de l'objet

Lien vers le commentaire
Partager sur d’autres sites

Enfin, Java n'est pas plus compliqué que C/C++ (je vais me faire taper dessus  :chinois: )

Non tu ne vas pas te faire taper sur les doigts :-D

L'objet en C++ n'est pas différent à l'exception de l'inexistance de la méta classe Objet.

Programmer de l'objet en C++ n'est pas réellement différent, si ce n'est tous les aspects "annexes" de gestion des pointeurs et la nécessité d'avoir une bonne connaissance de ce qu'il se passe en mémoire avec les données (heap, stack, segment .text). Mais je rajouterais surtout que même en Java il est nécessaire de bien comprendre comment est gérée la mémoire pour optimiser correctement son code.

Sinon bibisousnours fait bien attention à la différence entre les notions de classifier (prononcer classifayeur :transpi: ) et d'objet . On dira qu'un objet est une intance d'un classifier.

Lorsque l'objet a instancie la classe A qui elle même hérite ou implémente B alors a est aussi une instance du classifier B. Pour te représenter tout ça rappel toi de tes cours de maths info si tu en as déjà eu:

si a->A et A->B alors a->B (-> : implique)

soit :

a->A ^ A->B => a->B

Enfin bon je m'égare là :roll:

Lien vers le commentaire
Partager sur d’autres sites

J'ai pas compris ce que tu as raconté apres l'histoire des classifier et l'histoire des implications.

On m'a toujours dit qu'un objet est une intance d'une classe. Tu veux dire que classifier est l'equivalent en anglais de classe ?

Lorsque l'objet a instancie la classe A qui elle même hérite ou implémente B alors a est aussi une instance du classifier B. Pour te représenter tout ça rappel toi de tes cours de maths info si tu en as déjà eu:

si a->A et A->B alors a->B (-> : implique)

soit :

a->A ^ A->B => a->B

Si j'ai bien compris, voila ce que Fabrice a voulu dire :

Tu as une classe A

qui hérite ou implémente (si la classe B est abstraite, cad non instanciable) une classe B.

Ensuite tu crées une instance a de type A.

Alors a est de type instance A, mais aussi de type instance B.

Clair non ? :chinois:

Lien vers le commentaire
Partager sur d’autres sites

Si j'ai bien compris, voila ce que Fabrice a voulu dire :

Tu as une classe A

qui hérite ou implémente (si la classe B est abstraite, cad non instanciable) une classe B.

Ensuite tu crées une instance a de type A.

Alors a est de type instance A, mais aussi de type instance B.

Clair non ? :-D

Héhé oui c'est ce que j'ai voulu dire. Bon j'ai mis un peu de maths mais un zeste de théorie de temps en temps ça ne fait pas de mal.

Si j'ai fais cette remarque bibisousnours c'est pour que tu comprenne bien que si tu as deux classes A et B et que tu veux utiliser de manière interchangeable une variable pour référencer une instance de l'une ou l'autre de ces classes (ou classifiers) il faut alors remplir une condition : leur trouver une classe mère ou une interface mère qu'ils ont en commun.

Ainsi si A implémente ou hérite C

et si B implémente ou hérite C :

a->A et A->C => a->C

et

b->B et B->C => b->C

du coup on voit

b->C et a->C, ce qui revient à dire que l'instance b de la classe B et l'instance a de la classe A ont une classe commune C. En d'autres termes a et b sont de même nature C (en plus d'être l'une de nature A et l'autre de nature B).

J'espère que tu vois l'intérêt des maths info dans ce cas précis, ça permet d'exprimer de manière synthétique et simple ce que j'ai dit en langage naturel (ce qui m'a pris 5 lignes et une 30aine de mots en français au lieu de 2 lignes en langage matheux) :craint:

Du coup si tu veux une variable pouvant référencer aussi bien des objets de nature A ou B il te suffit de déclarer une référence de type C (tu me suis là?).

Ce qui donne en Java :

C c ;

c = new A(); // c references an A classifier instance

et ensuite tu peux faire :

c = new B(); // c references now a B classifier instance and the instance created by

// new A() goes in the garbage collector as non referenced anymore

Lien vers le commentaire
Partager sur d’autres sites

Si j'ai bien compris, voila ce que Fabrice a voulu dire :

Tu as une classe A

qui hérite ou implémente (si la classe B est abstraite, cad non instanciable) une classe B.

Ensuite tu crées une instance a de type A.

Alors a est de type instance A, mais aussi de type instance B.

Clair non ? :byebye:

Voilà, je reviens de TP, et c'est effectivement la solution qui a été adoptée :

La classe Forme est abstraite. De cette facon, en plus "implémentant" une méthode "dessine", ainsi qu'à toutes les autres classes qui héritent d'elle (Carre...), on a accès à

forme1.dessine(), qui dessinera par ex un carre, si forme1 a été créé avec le constructeur Carre().

Merci pour votre aide :craint:

Y'a plus qu'à voir en cours le double buffer et le programme devrait etre "terminé"..

Lien vers le commentaire
Partager sur d’autres sites

:francais:

Ca y est, ca se connecte, ca affiche les formes, ca supprime la 1ere quand on arrive à la 11eme, puis la 2eme pour la 12, etc...

reste à savoir utiliser le double buffer et surtout à fermer le programme quand je ferme la fenetre.

Si vous pouvez m'aider à ce sujet :

je crée une fenêtre qui est en fait une instance de Jframe. Mais quand je ferme la fenetre avec la "petite croix de windows" (en haut à droite), le programme continue à tourner. Or il faudrait qu'il s'arrete. De meme en faisant alt+F4, le programme tourne tout le temps, seule la fenetre se ferme.

Comment pourrais-je m'y prendre?

Edit : j'y arrive en utilisant:

fenetre.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

Mon soucis est qu'en faisant de la sorte, le client (donc mon programme) coupe la connection sans envoyer "END" au serveur qui lui ne libère donc pas ses ressources. Et le prof ne veut pas de ca. Il faudrait donc que je sache tester la fermeture de la fenetre et si elle est fermée, avant de terminer le programme à l'aide de (setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE):chinois: il faut que j'envoie "END" au serveur.

Comment tester la fermeture de la fenetre? :chinois:

j'ai essayé :

if(fenetre.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) {

...;

}

en espérant que la valeur puisse etre "vraie", mais ce ne fonctionne pas...

Lien vers le commentaire
Partager sur d’autres sites

Pour le double buffer, tu dois pouvoir facilement trouver de la doc sur le web

la technique n'est pas propre au Java

Sinon, "synthetiquement", voila comment ça fonctionne :

- tu as 2 surfaces (ou zones de dessin/mémoire)

l'une visible, l'autre non.

- tu affiches la 1ère.

pendant ce temps tu dessines sur l'autre (qui reste invisible)

- tu échanges les 2 surfaces

celle invisible s'affiche

celle visible devient invisible

Retour au 2ème point

C'est une technique très utilisée dans les jeux

car :

- l'affichage d'une zone rectangulaire est tres rapide (copie de memoire à mémoire)

- ca évite un effet de scintillement

Lien vers le commentaire
Partager sur d’autres sites

je crée une fenêtre qui est en fait une instance de Jframe. Mais quand je ferme la fenetre avec la "petite croix de windows" (en haut à droite), le programme continue à tourner. Or il faudrait qu'il s'arrete. De meme en faisant alt+F4, le programme tourne tout le temps, seule la fenetre se ferme.

http://java.developpez.com/faq/java/?page=..._fermer_fenetre

Est-ce que tu as vu en cours les "listeners" ?

si non, ca correspond "à peu près" à la gestion évènementielle sous VB ou VC++

Pour le double buffering :

http://java.developpez.com/faq/java/?page=...doublebuffering

Par contre, pour la gestion réseau ???

je n'ai pas vu cette partie....

Lien vers le commentaire
Partager sur d’autres sites

http://java.developpez.com/faq/java/?page=..._fermer_fenetre

Est-ce que tu as vu en cours les "listeners" ?

si non, ca correspond "à peu près" à la gestion évènementielle sous VB ou VC++

C est sur cette page que je m etais deja base. (dsl pour les accents, clavier US)

J avais pris la methode pour swing mais apparememt celle qu il me faut c est la premiere qui permet de faire d autres actions avant de fermer le programme.

Mais je ne sais pas où mettre ces lignes de code :

maFenetre.addWindowListener(new java.awt.event.WindowAdapter() {

public void windowClosing(java.awt.event.WindowEvent evt) {

hide();

}

} );

est-ce au même niveau que la creation des variables de la classe Fenetre ?

Lien vers le commentaire
Partager sur d’autres sites

1) déjà ta classe qui te sert de fenetre d'affichage doit heriter de Listener

2) ensuite c'est à la création ou à l'initialisation de cette fenetre

que tu dois rajouter le "addWindowListener"

Pour le code "exact", faut que je retrouve mes cours....

j'essayerai de voir ca avec le prof cette aprem. Je vous tiens au courant.

Toujours est il que je vous remercie beaucoup, j'ai 2 semaines d'avance sur le projet maintenant :pciwin:

Lien vers le commentaire
Partager sur d’autres sites

Un petit bout de code :

import java.awt.*;
import java.awt.event.*;

public class PushMe {
   static public void main(String argv[]) {
       new PushMe();
   }

   // Le constructeur de la classe PushMe
   public PushMe() {
       Frame f = new Frame("Ma fenêtre");
       Button b = new Button("Push me");
       b.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent event) {
               System.out.println("Bouton cliqué !");
           }
       });

       f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent event) {
               System.exit(0);
           }
      });

       f.add(b); // On ajoute le bouton dans la fenêtre
       f.pack();
       f.setVisible(true);
   }
}

Explication du code :

Ici, on a 1 fenêtre et on a ajouté 1 bouton sur cette fenetre.

On a ensuite ajouté la gestion de l'evenement "cliquer"

sur le bouton (methode addActionListener)

puis sur la fenetre (methode addWindowListener)

Aparté

Dans la méthode addActionPerformed

tu peux gérer la variable event

tu peux ainsi gerer, l'appui, le relachement, determiner quel bouton a appuyé, ...

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...