Newsgroup: it.comp.java
Titolo: Non trova la variabile...

Salve a tutti, ho iniziato a studiare java da 2 giorni per motivi 
universitari e sto facendo tutta una serie di esempi per capire il 
funzionamento
ho fatto questo stupido programmino, che dovrebbe restituire un ipotetico 
valore numerico del serbatoio sinistro di un aereo...
solo che quando chiamo il metodo, non trova la variabile, dove sta l'errore?
grazie
class Serbatoio {
    public Serbatoio(int i) {
    Serbatoio sx = new Serbatoio(50);
    Serbatoio dx = new Serbatoio(70);
}
        void ControllaCapacita() {
            System.out.println("La capacità del serbatoio è di " + i + " 
litri");
        }
   }
public class Aereo {
    public static void main(String[] args) {
        Aereo F16 = new Aereo();
        F16.sx.ControllaCapacita();
    }
}
-- 
*---------------> David`125 <--------------*

    }
Sono abbastanza agli inizi pure io (tra l'altro uso J2ME, ma la sintassi 
dovrebbe essere la  stessa), ma credo che il problema sia nel costruttore 
della classe Serbatoio.
Mettendo Serbatoio sx e dx gli dici di creare due nuovi oggetti Serbatoio 
ogni volta che ne crea uno. Il che creerebbe un loop. Lui però si ferma 
prima, credo (non hai dato l'errore preciso) perché nella dichiarazione 
del costruttore "(int i)" significa che il costruttore ha bisogno di un 
intero i che non gli viene dato quando usi Aereo. Un altro errore è in 
ControllaCapacita, che chiama la variabile i; inserendola in questo modo 
tu dici al programma che la variabile è inizializzata all'interno di 
ControllaCapacita (quella riferita alla classe sarebbe this.i) e quindi il 
programma non può trovarla.
In generale credo che più che correggere dovresti rivedere il programma da 
zero.
See you,
        Silver Drake
-- 
Paperblog: l'irriverente blog della famiglia pinguina
http://www.silverdrakenet.it/blog/blog.html
Quello che scrive il Drake è la verità (gg)
RADIO HELL: 
http://www.myspace.com/rh666

innanzitutto ti ringrazio per la risposta
ho fatto delle correzioni, per iniziare a far compilare il programma, ora 
rimane solo la variabile non trovata.
Così facendo, il file viene compilato, e F16.sx.ControllaCapacita viene 
correttamente invocato, e restituisce la stringa di testo "la capacità è bla 
bla"
l'uso di this non mi è chiarissimo (avrò riletto 200 volte a cosa serve su 
thinking in java ma ho sempre dubbi!)
class Serbatoio {
    public Serbatoio(int i) {  }
        public void ControllaCapacita() {
            System.out.println("La capacità del serbatoio è di litri");
        }
    }
public class Aereo {
            static Serbatoio sx = new Serbatoio(50);
            static Serbatoio dx = new Serbatoio(70);



1) La variabile i [public Serbatoio(int i)] è visibile solo all'interno
del costruttore.
3) Le stesse variabili Serbatoio sx e Serbatoio dx sono visibili solo
all'interno del costruttore ( tra "{" e "}"); non dovrebbero quindi,
come i, essere visibili dal metodo ControllaCapacita
3) Una volta risolto il problema dell'errore in compilazione, si creerà
un loop che genererà un errore di stack overflow a runtime:
Serbatoio(int i) richiama Serbatoio sx = new Serbatoio(50), che a sua
volta richiama public Serbatoio(int i), e così via all'inficito.
4) La variabile i all'interno del costruttore non viene usata, quindi
non capisco a cosa serve: le capacità sembrerebbero settate per forza a
50 e 70.
5) Nella classe Aereo, all'interno del main, viene richiamato il
costruttore di Aereo (che non esiste), mentre quello di serbatoio non
viene usato da nessuna parte.
6) Non esiste nessuna proprietà sx di Aereo (e neanche di Serbatoio, o 
meglio in Serbatoio è una variabile interna al costruttore, che nasce e 
muore con esso), e tanto meno un metodo ControllaCapacita di sx 
(dovrebbe essere istanzaDiSerbatoio.ControllaCapacita(), e non 
istanzaDiAereo.proprietàCheNonEsiste.ControllaCapacita()).
N.B. [poco importante] Per convenzione, per quanto non sia errato 
operare diversamente, i
metodi dovrebbero avere l'iniziale minuscola, quindi controllaCapacita()
è preferibile.
Quanto segue non credo corrisponda del tutto alle tue intenzioni, ma 
tanto per correggere gli errori:
class Serbatoi
  {
   private int sinistro;
   private int destro;
   public Serbatoi(int sinistro,int destro)
    {
     this.sinistro=sinistro;
/* alla variabile sinistro della classe
(this.sinistro, ovvero quella prima di public Serbatoi)
viene assegnato il parametro del costruttore
(sinistro, ovvero quello subito dopo public Serbatoi)*/
     this.destro=destro;
/*stessa cosa*/
    }
   public void controllaCapacita()
    {
     System.out.println("La capacità del serbatoio sinistro è di " + 
sinistro + " litri");
/* qui si può sottintendere this,
e scrivere sinistro al posto di this.sinistro,
in quanto tra le graffe di controllaCapacita
non è definita una variabile sinistro
come nel caso del costruttore*/
     System.out.println("Quella del serbatoio destro è di " + destro + " 
litri");
/*come sopra*/
    }
  }
public class Aereo
  {
   public static void main(String[] args)
    {
     Serbatoi serbatoiF16 = new Serbatoi();
     SerbatoiF16.sx.ControllaCapacita();
    }
  }

 
class Serbatoio {
      *private int capacita = 0;*
      public Serbatoio(int i) {
	*this.capacita = i;*
	}
          public void ControllaCapacita() {
              System.out.println("La capacità del serbatoio è di 
"+this.capacita+" li$
          }
      }
  public class Aereo {
              static Serbatoio sx = new Serbatoio(50);
              static Serbatoio dx = new Serbatoio(70);
              public static void main(String[] args) {
                  Aereo F16 = new Aereo();
                      F16.sx.ControllaCapacita();
      }
}
;)

 quando chiamo il metodo, non trova la variabile, dove sta l'errore?
la variabile 'i' è un parametro del costruttore, è visibile nel 
costruttore e non nel metodo ControllaCapacita().
ps: occhio che quel serbatoio esplode...

> per correggere gli errori:
Forse così è meglio:
class Serbatoio
  {
   private int size;
   public Serbatoi(int size)
    {
     this.size=size;
    }
   public int getSize()
    {
     return size;
    }
  }
public class Aereo
  {
   private Serbatoio left;
   private Serbatoio right;
   private void controlloCapacita()
    {
     System.out.println("La capacità del serbatoio sinistro è di " +
left.getSize() + " litri");
     System.out.println("Quella del serbatoio destro è di " + 
right.getSize() + "
litri");
    }
   public Aereo(int sxSize,int dxSize)
    {
     left=new Serbatoio(sxSize);
     right=new Serbatoio(dxSize);
    }
   public static void main(String[] args)
    {
     Aereo F16 = new Aereo(50,70);
     F16.controllaCapacita();
    }
  }

il 12/01/2009 13.41, Scrive David`125 43513736:

I problemi sono diversi.
Il piu' facile:
 >> System.out.println("La capacità del serbatoio è di " + i + "
la variabile i non e' dichiarata, ovvero c'e' una dichiarazione con 
visibilita' locale come argomento del costruttore:
public Serbatoio(int i)
  ma essendo locale e' visibile solo nel corpo del costruttore, dove 
però non ne fai uso.
Nel costruttore dichiari due variabili, sx e dx la cui visibilita' 
termina quando il costruttore termina la sua esecuzione. Sempre che 
termini, secondo me non termina mai poiche' richiama se stesso 
all'infinito. Infatti:
Serbatoio sx = new Serbatoio(50);
istanzia una nuova classe di tipo Serbatoio che a sua volta istanzia due 
classi di tipo Serbatoio che a loro volta fanno lo stesso fino a quando 
non finisci la memoria disponibile.
Dovrebbe essere che la classe Aereo possiede due Serbatoio, quindi:
public class Aereo {
   Serbatoio sx;
   Serbatoio dx
   public Aereo() {
 
this.sx
 = new Serbatoio(50);
     this.dx = new Serbatoio(70);
   }
   public static void main(String[] args) {
     Aereo F16 = new Aereo();
     F16.sx.ControllaCapacita();
   }
}
Cosi' il costruttore Aereo assegna un valore iniziale ai serbatoi. La 
classe Serbatoio dovra' analogamente "ricordarsi" la sua capacita', quindi:
class Serbatoio {
   int i;
   public Serbatoio(int i) {
     this.i = i;
   }
   public void ControllaCapacita() {
     System.out.println("La capacità del serbatoio è di "+i+" litri");
   }
}
In questo caso "this", che rappresenta l'istanza della classe stessa, 
diventa indispensabile, poiche' altrimenti non sapresti come fare a 
distinguere tra l'argomento "i" e la variabile di classe "i".
Il modificatore public che ho messo nel metodo ControllaCapacita e' 
necessario poiche' altrimenti sarebbe visibile solo all'interno dello 
stesso package della classe Serbatoio; poiche' il package non e' 
dichiarato, la classe Aereo non potrebbe accedere al metodo.
Stessa cosa valga per i due serbatoi: senza il modificatore public, sx e 
dx sono visibili solo nella classe Aereo, per cui F16.sx non potrebbe 
funzionare se utilizzato da una classe diversa da Aereo.
Lo stesso dicasi per la classe Serbatoio: senza modificatore public la 
visibilità e' ridotta al solo package. In alternativa puoi dichiarare la 
classe Serbatoio interna ad Aereo, ovvero:
public class Aereo {
   class Serbatoio {
     int i;
     public Serbatoio(int i) {
       this.i = i;
     }
     public void ControllaCapacita() {
       System.out.println("La capacità del serbatoio è di "+i+" litri");
     }
   }
   Serbatoio sx;
   Serbatoio dx
   public Aereo() {
 
this.sx
 = new Serbatoio(50);
     this.dx = new Serbatoio(70);
   }
   public static void main(String[] args) {
     Aereo F16 = new Aereo();
     F16.sx.ControllaCapacita();
   }
}
cosi' facendo Serbatoio e' visibile solo da Aereo ed hai bisogno di un 
solo file Aereo.java, mentre nel caso precedente dovresti avere anche il 
file Serbatoio.java.
Altra cosa: in genere, per convenzione, i nomi dei metodi dovrebbero 
iniziare con lettera minuscola, a differenza dei nomi delle classi che 
dovrebbero iniziare con lettere maiuscola.
-- 
Dr.Ugo Gagliardelli,Modena,ItalyCertifiedUindoscrasherAñejoAlcoolInside
Spaccamaroni andate a cagare/Spammers not welcome/Spammers vão à merda
Spamers iros a la mierda/Spamers allez vous faire foutre/Spammers loop
schijten/Spammers macht Euch vom Acker/Spamerzy wypierdalac'

> ;)
grazie 1000
quindi ci ero andato vicino :)
approfitto solo per farti una domanda da ignorante :)
class Serbatoio {
    private int capac;
    public Serbatoio(int i) {
        this.capac = i;
    }
            public void ControllaCapacita() {
            System.out.println("La capacità del serbatoio è di " + 
this.capac + " litri");
        }
    }
Perchè c'è bisogno di creare un'altra variabile (capac nel caso in oggetto) 
per far funzionare il tutto, ed invece non è possibile fare direttamente 
this.i = i ?
grazie ancora
David 


si è molto chiaro grazie, anche se molto diverso dal mio basilare modo di 
pensare :)
-- 
*---------------> David`125 <--------------*
#->...Che A Quella Di Dietro Ci Penso Io <-# 

il 12/01/2009 15.35, Scrive David`125 43513736:

Come dicevo nel mio post, la variabile i dichiarata in Serbatoio(int i) 
nasce e muore nel corpo del metodo, this.i invece si riferisce ad una 
variabile dichiarata nel corpo della classe e quindi permane finche' 
l'oggetto ha vita, nel caso sopra,
private int capac;
potrebbe essere
private int i;
ma deve essere comunque dichiarata, il fatto che "i" dichiarata nella 
classe ed "i" dichiarata nel metodo si chiamino allo stesso modo, non 
comporta che identifichino lo stesso valore/oggetto, per questo motivo, 
allo scopo di differenzairle, usi this.i ed i.
