Type STATIC (n°2)

BSide Messages postés 88 Date d'inscription mercredi 13 février 2002 Statut Membre Dernière intervention 18 février 2008 - 29 juil. 2003 à 20:39
BSide Messages postés 88 Date d'inscription mercredi 13 février 2002 Statut Membre Dernière intervention 18 février 2008 - 7 août 2003 à 14:01
Bonsoir,

j'ai un problème de compréhension du caractère "static" d'une variable ou d'une méthode. Je ne comprends pas vraiment à quoi ça sert. En quoi le résultat serait-il différent si je ne déclarais pas mes variables et méthodes "static".

Actuellement, j'ai créé une classe de distribution aléatoire d'un jeu de cartes (je débute, donc ce n'est pas très ambitieux, mais bon...).

Mes variables et méthodes sont toutes de type "static". Pourquoi ? Parce que si je ne mets pas "static" partout, j'obtiens l'erreur suivante à l'exécution :

java.lang.NoSuchMethodError: main
Exception in thread "main"

Donc : je rajoute "static" à ma méthode "main". Ce qui m'oblige ensuite à l'ajouter de partout puisque les méthodes non "static" ne veulent pas s'exécuter avec un main "static" et que le fait d'ajouter "static" à mes méthodes m'oblige dans un second temps à déclarer "static" certaines de mes variables.

Merci de m'aider à comprendre ce qui se passe.

BSide
:)

4 réponses

CoreBreaker Messages postés 540 Date d'inscription dimanche 23 mars 2003 Statut Membre Dernière intervention 5 octobre 2007 1
30 juil. 2003 à 02:14
static indique que la méthode ou l'attribut (variable) est de classe c'est à dire commune à toutes les instances, toutes les instances voie la même variable:

class c
{
private static int i= 0;

public c()
{
i++;
}

static void print()
{
System.out.println("i=" + i);
}

}

Si tu fait:
c c1= new c();
c c2= new c();


Et ensuite que tu fasses:
c1.print();
ou
c2.print();
ou
c.print();
cela produit la même chose.

En fait i et print() sont définis au niveau pas de la classe. Car si tu fait:
class cc
{
private static int i= 0;
private int j= 0;
private int k= i;

public cc()
{
i++;
j++;
}

public void inc()
{
j++;
}

public static void s_inc()
{
i++;
}

void print()
{
System.out.println("i=" + i);
System.out.println("j=" + j);
System.out.println("k=" + j);
}

}

Ici déja tu ne peux plus faire cc.print() car la méthode print() n'est plus de classe mais d'instance c'est à dire que l'exécution de cette méthode se fera spécifiquement à une instance:
cc cc1= new cc();
cc cc2= new cc();
Tu verras qu'en faisant:
cc1.print(),

et en faisant:
cc2.print(),
la valeur i, et la valeur de j, dans les deux cas on certes la même valeur mais que i as la valeur 2 donc le nombre de fois que la classe est instanciée mais que j a la valeur 1 car à chaque instance l'attribut j est à 0 et donc que chaque instance c'est un nouveu attribut j qui est spécifique à la nouvelle instance. De plus, puisque k prend la valeur de i courante les valeurs de k sont différentes et donc bien spécifiques. Tu peux t'en convaincre en faisant:
cc1.inc();
cc1.print();
cc2.print();
tu vois bien que seul l'attribut j de l'instance cc1 a été incrémenté. Alor qu'en faisant:
cc1.inc();
cc1.print();
cc2.print();
L'attribut i a été incrémenté pour les 2 instances.
Ca aurait été la même chose en faisant:
cc.inc();
cc1.print();
cc2.print();
Bref à partir de l'indentificateur de la classe.

C'est FAUX une méthode statique ne force pas à utiliser un attribut ou une méthode statique (dits de classes):
class essai
{
public essai()
{
}

public void f()
{
e.f2();
}

static public void f2()
{
}

public static void main(String[] args)
{
essai e= new essai();
e.f();
}
}
Ici j'ai appelé la méthode f() qui n'est pas statique à partir la méthode main qui elle est statique.

Il est clair que je ne peux pas faire essai.f() car f n'est pas statique seule une instance peut l'appelée. Mais aussi t'as vu, j'ai fais e.f2(); car une instance peut appeler une méthode statique (de classe) tout comme accéder à un attribut de classe comme j'ai fait dans mes exemples précédents. Car une méthode a déjà les infos de sa propre classe. Alors qu'une classe peut créer plusieurs instance, un appel donc à essai.f() est prohibé car on ne sais pas à quelle instance on se rapporte.

Bref, tu mets en static tout ce qui est commun à tous les objets d'une même classe comme un compteur d'instance comme pour la classe "c"

Core Breaker :)
0
tominfo Messages postés 93 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 30 janvier 2009
30 juil. 2003 à 08:58
-------------------------------
Réponse au message :
-------------------------------

CoreBreaker t'as donné une magnifique réponse ! Je crois que tout est dit!
En lisant ton message j'avais l'impression que tu avais oublié que Java est un langage objet.
En programmant de la sorte :
public class A {

public A() {
}

public void f1(){
}

public void f2() {
}

public static void main(String[] args) {

          f1();
          f2();
}
}


Ceci n'est pas bon au niveau conception car tu n'utilise pas les objets... (en plus tu auras des pb à cause du static). Tu travaille comme si tu étais sur du C ou du Pascal... (tu appelles des fonctions et non les méthodes des objets)

Par contre si tu travailles comme ceci :
public class A {

public A() {
}

public void f1(){
}

public void f2() {
}

public static void main(String[] args) {

          A a = new A();
          a.f1();
          a.f2();
}
}


Là pas de problème : tu crée une instance de ta classe A et tu utilises les méthodes qui lui sont propres (qu'elles soient static ou non)
0
BSide Messages postés 88 Date d'inscription mercredi 13 février 2002 Statut Membre Dernière intervention 18 février 2008
7 août 2003 à 13:56
Bonjour,

je prends connaissance de ta réponse à mon message et je tiens à te remercier vivement pour cette explication LUMINEUSE.

Je ferai qq essais ce week end pour bien voir les résultats que tout cela produit et manipuler ces concepts.

Merci encore pour le temps important que tu m'as consacré et très bonnes vacances si tu n'es pas encore parti.

@+

BSide
:)
0
BSide Messages postés 88 Date d'inscription mercredi 13 février 2002 Statut Membre Dernière intervention 18 février 2008
7 août 2003 à 14:01
Bonjour,

tu n'es pas le premier à me dire que je ne pense pas "objet", mais ça va mieux en le disant.

Tu as raison, je ne suis pas tout à fait habitué à cette façon de penser. La difficulté est triple :
- apprendre ce nouveau langage certes élégant mais complexe
- penser objet
- oublier de raisonner "procédure", "cause-effet", bref "séquenciel"

Merci pour ta réponse. A bientôt.

BSide
:)
0
Rejoignez-nous