BSide
Messages postés88Date d'inscriptionmercredi 13 février 2002StatutMembreDernière intervention18 février 2008
-
29 juil. 2003 à 20:39
BSide
Messages postés88Date d'inscriptionmercredi 13 février 2002StatutMembreDernière intervention18 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.
CoreBreaker
Messages postés540Date d'inscriptiondimanche 23 mars 2003StatutMembreDernière intervention 5 octobre 20071 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"
tominfo
Messages postés93Date d'inscriptionsamedi 17 mai 2003StatutMembreDernière intervention30 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)
BSide
Messages postés88Date d'inscriptionmercredi 13 février 2002StatutMembreDernière intervention18 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"