Probème de variable

Résolu/Fermé
speedzealot Messages postés 18 Date d'inscription vendredi 24 juillet 2015 Statut Membre Dernière intervention 17 novembre 2015 - Modifié par speedzealot le 24/07/2015 à 15:37
speedzealot Messages postés 18 Date d'inscription vendredi 24 juillet 2015 Statut Membre Dernière intervention 17 novembre 2015 - 27 juil. 2015 à 19:25
bonjour a tous, en simplifiant mon code, cela donne ca :

public class Mere {

protected Integer integer;
private Thread t;

    public Mere() {
         integer = 1;
         t = new Thread(new ClasseFille());
    }

    public void update() {
         if (t.getState() == State.NEW) t.start();
    }

}


public class ClasseFille extends Mere implements Runnable {

    public ClasseFille() {
    }

    public void run() {
         System.out.println(integer); //et au lieu de m'afficher 1, il m'affiche null...
    }

}




Pourquoi ? et comment y remedier ?
merci de vos reponses

1 réponse

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
24 juil. 2015 à 21:00
Bonjour,

Tu as redéfini le constructeur de la classe, ce qui efface celui de la classe mère, alors que c'est elle qui fait l'initialisation...

    public ClasseFille() {
        super(); // appel du constructeur Mere() qui fait integer=1
    }
1
Merci KX, je testerai ca lundi, je vous tiendrai au courrant
0
speedzealot Messages postés 18 Date d'inscription vendredi 24 juillet 2015 Statut Membre Dernière intervention 17 novembre 2015 3
Modifié par speedzealot le 27/07/2015 à 10:02
donc non, ca ne marche toujours pas

je vais developper mon probleme :
J'utilise Slick2D et ma classe mere c'est ma fenetre de jeu.
je voudrai creer un nouveau thread depuis cette classe mere et, que ce nouveau thread hérite des variables de classes de ClasseMere (parce que je n'ai pas vraiment envis de creer des accesseurs pour ces 10 parametres, ni meme de changer la portee de ces parametres à "package", ca me compliquer trop le travail de maintenance et ce serai plus lourd a l'execution, sachant que ce thread va faire une grosse serie d'action assez lourde, sans s'arreter)

Donc ce thread j'ai voulu le faire implementer l'interface Runnable.

public class Mere extends BasicGame{

protected Integer integer;
//d'autres variables de classes protected
private Thread t;

    public Mere() {
         super("mon jeu");
    }

    @Override
    public void init(GameContainer container) {
         integer = 1;
         //initialisation des variables de classe
         t = new Thread(new ClasseFille());
    }

    @Override
    public void render(GameContainer container) {
         if (t.getState() == State.NEW) t.start();
    }

}

public class ClasseFille extends Mere implements Runnable {

    public ClasseFille() {
    }

    public void run() {
         System.out.println(integer); //et au lieu de m'afficher 1, il m'affiche null...
         //idem pour les autres variables de classe..
    }

}


peut-on vraiment creer un heritage de cette maniere en passant par la classe mere qui est deja instanciée ou dois-je revenir sur une methode moins subtile ?
0
speedzealot Messages postés 18 Date d'inscription vendredi 24 juillet 2015 Statut Membre Dernière intervention 17 novembre 2015 3
27 juil. 2015 à 10:10
enfin pour l'incetant j'ai a moitié resolu mon probleme en enlevant l'heritage et en mettant en parametre ClasseMere dans le constructeur de ClasseFille (qui n'est donc plus vraiment une classe fille) mais j'aimerai quand meme bien que cette classe accede directement a tous les parametres de ClasseMere
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 27/07/2015 à 19:26
En fait ton problème ce n'est pas de l'héritage.

L'héritage c'est pour des classes afin qu'elles génèrent des objets qui ont des comportement communs, plus une spécificité pour l'objet de la classe fille.
On parle donc de deux objets totalement distincts, qui n'interagissent pas entre eux, c'est leur code qui est commun, pas leurs états.

Avec :
public Mere() {
    integer = 1;
    t = new Thread(new ClasseFille());
}
public ClasseFille() {
    super(); // appel du constructeur Mere() qui fait integer=1
}
Ici ça va fonctionner, on va bien avoir integer==1 dans l'objet ClasseFille car le constructeur a appelé le code de Mere.

Avec :
public void init(GameContainer container) {
    integer = 1;
}
public ClasseFille() {
}
Ici ça ne fonctionne pas, car l'objet de ClasseFille est construit sans rien faire, il faudrait appeler la méthode init() pour l'objet fille - de la même manière que pour l'objet Mere - afin que cela fonctionne.

Si j'ai bien compris ce que tu cherches à faire, c'est suivre dans tous les objets de ClasseFille l'évolution de l'état d'un objet Mere en particulier. Mais ce n'est pas de l'héritage.

Passer en paramètre l'objet Mere à ClasseFille (qui n'est de toute façon pas une classe fille puisque l'héritage ne sert à rien dans ton cas) est pour moi la manière la plus propre de faire. Il en existe une manière plus directe mais si tu peux éviter c'est mieux, voici un exemple (on appelle ça des inner classes) :

public class Mere extends BasicGame {

    private Integer integer; // plus besoin de protected

    // ...

    public Mere() {
        super("mon jeu");
    }

    @Override
    public void init(GameContainer container) {
        integer = 1;
        // ...
    }

    public class Fille implements Runnable {

        @Override
        public void run() {
            System.out.println(integer);
        }
    }

    public static void main(String[] args) {
        Mere m1 = new Mere();
        Mere m2 = new Mere();

        Fille f11 = m1.new Fille();
        f11.run(); // null

        m1.init(null);
        f11.run(); // 1

        Fille f12 = m1.new Fille();
        f12.run(); // 1

        Fille f2 = m2.new Fille();
        f2.run(); // null
    }
}

Remarque : je te conseilles de renommer tes classes Mere et Fille, car il n'y a vraiment aucune relation d'héritage ici.

Une troisième manière de faire, serait de mettre les deux classes en une (à ne pas utiliser si BasicGame implémente déjà Runnable, c'est à dire si la classe Mere hérite d'une méthode run() que ce code viendrait remplacer à tort).

public class Mere extends BasicGame implements Runnable {

    private Integer integer;
    //d'autres variables de classes private
    private Thread t;

    public Mere() {
         super("mon jeu");
    }

    @Override
    public void init(GameContainer container) {
         integer = 1;
         //initialisation des variables de classe
         t = new Thread(this);
    }

    @Override
    public void render(GameContainer container) {
         if (t.getState() == State.NEW) t.start();
    }

    @Override
    public void run() {
         System.out.println(integer);
    }
}
0
speedzealot Messages postés 18 Date d'inscription vendredi 24 juillet 2015 Statut Membre Dernière intervention 17 novembre 2015 3
27 juil. 2015 à 19:25
merci beaucoup ! avec les classes interner ca marche nickel :) du coup je vais pouvoir commencer le multithreading d'un peu partout pour optimiser une grande partie du code ! j'ai deja gagné 200 fps :) et avec quelques un en plus je pourrai gagner encore quelques centaines de fps (ils me seront utiles quand j'implementerai de plus en plus d'elements graphiques a mon jeu)

(mes classes ne s'appelles pas du tout ClasseMere et ClasseFille, c'etait juste pour les rendre plus explicite dans ma demande ^^)

enfin la ca marche tres bien :) et les threads fonctionnent bien simultanément :)
0