Aiutino per richiamare metodi di altre classi?

di il
40 risposte

Aiutino per richiamare metodi di altre classi?

Ciao a tutti ragazzi..ho iniziato a studiare java da pochi mesi. Ieri stavo provando a fare un programma che registri un utente all'aeroporto. Viene inserito il nome, il cognome e poi viene assegnato un numero identificativo(che va da 0 a 9). E' possibile inserire un altro utente subito dopo che viene registrato il primo e poi è possibile stampare la lista di tutti i passeggeri registrati. Ho solo qualche problemino. Per il momento l'ho fatto tutto in due classi, una il main e l'altra che contiene tutti i metodi. Vorrei provare a fare almeno la stampa di tutti i passeggeri in un altra classe, ma non riesco ad accedere al metodo esterno, anche facendo un extends della classe che contiene le variabili o i vettori che mi servono. Inoltre(e qua sarà una cosa banalissima) non riesco ad incrementare il numero che viene assegnato all'utente. Ovvero, il primo che si registra ha come numero "0", ma poi anche il secondo, il terzo e così via hanno sempre "0". Ho provato con un for ma poi mi stampa dieci volte "le è stato assegnato il numero 0". Vi posto il codice con anche i commenti cosi mi dite se potete darmi una mano

package aeoroporto;
import java.util.Scanner;

public class Registrazioni {
    
     
   
     protected String[] nome = new String[10];
     protected String[] cognome = new String[10];
     protected int i;
     protected int[] numero = new int[10];
     private String risposta;
     
   
    
    public void registraNome(){
       System.out.println("Benvenuto! Compili il modulo di registrazione sottostante...");
        System.out.println("Inserisca il suo nome: ");
        Scanner tastiera = new Scanner(System.in);
        for(int i=0; i<nome.length; i++);
        nome[i] = tastiera.nextLine(); //inserimento del nome da tastiera
        System.out.println("Il nome inserito è: " + nome[i]); //verifica del nome inserito
        registraCognome(); //chiamata al metodo registraCognome
      }
    public void registraCognome(){
        System.out.println("Inserisca il suo cognome: ");
        Scanner tastiera = new Scanner(System.in);
        for(int i=0; i<cognome.length; i++);
        cognome[i] = tastiera.nextLine();
        System.out.println("Il cognome inserito è: " + cognome[i]);
        assegnaNumero();
    }
    //metodo assegnaNumero da sistemare perchè il numero non incrementa
    public void assegnaNumero(){
        for(int i=0; i<numero.length; i++); /* for che dovrebbe incrementare il vettore numero 
        ogni volta che viene registrato un nuovo utente */
        System.out.println("Le è stato assegnato il numero : " + numero[i]);
                
        continuare();
       
        
    }
    
    public void continuare(){
        
        System.out.println("Vuoi registrare un altro utente?");
        Scanner tastiera = new Scanner(System.in);
        risposta = tastiera.nextLine();
        if(risposta.equalsIgnoreCase("Si")){
            i++;
            registraNome(); //se l'utente decide di continuare, si ritorna al metodo registraNome
            
        }else{
            System.out.println("Si desidera stampare la lista dei passeggeri?");
                    risposta = tastiera.nextLine();
                    if(risposta.equalsIgnoreCase("Si")) /*se l'utente digita si, viene 
                        richiamato il metodo stampa
                        */
                            stampa();
                    
        else{
                System.out.println("Grazie per avere scelto il nostro programma");
                } //il programma viene terminato
    }
    }
     public void stampa(){
         for(int i=0; i < 10; i++){
        if(nome[i]!= null && cognome[i] != null){
             System.out.println("Nome : " + nome[i] + " " + "Cognome : " + cognome[i] +" " + "Numero : " + numero[i]);
         }
    }
     }
}

Grazie in anticipo!
Edit: è normale che il codice si veda tutto verde? ho usato i tag Code e l ho messo all'interno...però si vede cosi...se si può sistemare ditemelo, perchè cosi forse è illegibile

40 Risposte

  • Re: Aiutino per richiamare metodi di altre classi?

    Prima di tutto hai qualche motivo particolare per lavorare con gli array nome, cognome e numero in parallelo?
    E' una pessima idea, contraria al paradigma della programmazione ad oggetti, e ti complica la vita per niente.

    Comincia con il creare una classe Passeggero, che contenga all'interno i campi nome, cognome e numero. Questo tra l'altro ti semplifica la vita nel metodo stampa (non hai bisogno di lavorare in parallelo sugli array, né di controllare che sia nome e cognome siano diversi da null, basta che non lo sia il Passeggero) permettendoti di avere un metodo specifico per stampare a video un Passeggero (non so se hai già visto l'override di toString(), ma è un concetto abbastanza semplice).

    Altro consiglio: crea un solo oggetto Scanner (puoi tenere l'oggetto come campo nella classe Registrazioni), ed usa un solo metodo per registrare un nuovo passeggero, senza complicarti la vita con la catena di metodi registraXXX.

    Come incrementare il numero di passeggeri dipende, la soluzione più semplice è mantenere una variabile statica in Passeggero, che incrementi all'intero del costruttore, puoi mantenere il numero anche in Registrazioni, ma devi ricordarti di incrementarlo solo una volta registrato un Passeggero nuovo.

    Con i cicli stai facendo invece una confusione enorme, innanzitutto quando scrivi:
    for(int i=0,....)
    stai ridichiarando la variabile i, quindi all'interno del ciclo la i che hai definito come campo di Registrazioni non viene modificata, inoltre il corpo del ciclo deve essere racchiuso tra parentesi graffe (come hai fatto solo in stampa, le parentesi possono essere omesse se il for ha un'unica istruzione), gli altri cicli che hai scritto vengono subito terminati con il punto e virgola, non hanno senso ...

    [Edit] Dimenticavo, se hai definito stampa come public, non c'è alcun problema a richiamarlo da una classe esterna, bisognerebbe vedere come stai facendo la chiamata...
    Comunque se segui il mio consiglio di costruire una classe Passeggero (magari anche ridefinendo toString() all'interno), potrai salvarti un array di Passeggeri e ciclare su quell'array, poi all'interno dell'array basta "stampare a video" l'oggetto Passeggero...

    Ps: Il codice va benissimo come l'hai inserito, forse colorato in modo diverso sarebbe ancora più leggibile, ma così è molto meglio rispetto a lasciarlo sciolto nel messaggio.
  • Re: Aiutino per richiamare metodi di altre classi?

    Grazie per la risposta ansharja.
    Si, immaginavo che il codice fosse molto confuso..d'altronde lo sono anch'io e alcune cose ancora non riesco a capirle.
    Quindi nella classe passeggero, nome, cognome e numero non devono essere dei vettori ma delle semplici stringhe e interi(per il numero) e devo poi inserirli in un unico array(passeggeri) che verrà stampato su richiesta?
    Il toString() non l'ho mai usato..ho dato un occhiata veloce adesso..in pratica mi trasforma ad esempio un intero in una stringa? Ho visto da un sito questo codice di esempio:
    public class Test { 
    
       public static void main(String args[]) {
          Integer x = 5;
    
          System.out.println(x.toString());  
          System.out.println(Integer.toString(12)); 
       }
    }
    l'output sarebbe 5 e 12.
    Questo metodo mi serve per stampare quindi il vettore con i 3 campi(nome,cognome e numero) insieme?
    edit: altra cosa..l'input da tastiera del nome e del cognome lo devo fare dalla classe registrazioni oppure dalla classe passeggero?
  • Re: Aiutino per richiamare metodi di altre classi?

    Ho provato a rifare il codice ragazzi..ho aggiunto la classe passeggeri..anche se non so se è giusto quello che ho fatto(ho preso spunto da degli esempi di un libro di java..però molte cose che ho messo non le ho capite(tipo tutti quei costruttori della classe passeggeri). Vi metto il codice..sono 3 classi
    Questa è la classe registrazione che richiama il metodo registra() in passeggeri
    package aeoroporto;
    
    import java.util.Scanner;
    
    public class Registrazioni {
    
        public Passeggeri[] persone;
    
        public void benvenuto() {
    
            System.out.println("Benvenuto! Compili il modulo sottostante.");
            System.out.println("Caricamento in corso...");
            persone = new Passeggeri[10];
            for (int i = 0; i < 10; i++) {
                persone[i] = new Passeggeri();
                persone[i].registra();
                System.out.println();
    
            }
        }
    }
    Questa è la classe passeggeri:
    package aeoroporto;
    
    import java.util.Scanner;
    
    public class Passeggeri {
    
        private String nome;
        private String cognome;
        private int numero;
        private String risposta;
        Scanner tastiera = new Scanner(System.in);
    
        public Passeggeri() {
            nome = "Nessun nome";
            numero = 0;
        }
    
        public Passeggeri(String nomeIniziale, int numeroIniziale) {
            setPasseggero(nomeIniziale, numeroIniziale);
    
        }
    
        public void setPasseggero(String nuovoNome, int nuovoNumero) {
            nome = nuovoNome;
            numero = nuovoNumero;
        }
    
        public void registra() {
            System.out.println("Inserisca il suo nome : ");
            
            nome = tastiera.nextLine();
            System.out.println("Il nome inserito è : " + nome);
            System.out.println("Le è stato assegnato il numero " + numero);
            numero++;
            continuare();
            
        }
        public void continuare(){
            System.out.println("Si desidera continuare?");
            risposta = tastiera.nextLine();
            if(risposta.equalsIgnoreCase("si")){
                registra();
            }
            else{
                stampaPasseggeri();
            }
        }
    
        public void stampaPasseggeri() {
            System.out.println("Nome : " +getNome());
            System.out.println("Numero : " +getNumero());
            
            }
        
    
        public String getNome() {
            return nome;
        }
    
        public int getNumero() {
            return numero;
        }
    
    }
    Poi vabbè, c'è il main che richiama la classe registrazioni da cui parte tutto. L'unico problema è che il metodo stampa nella classe passeggero stampa solamente l'ultimo nome inserito..e non tutto il vettore..ho provato in mille modi ma davvero non so come fare...
  • Re: Aiutino per richiamare metodi di altre classi?

    Intanto rispondo a questo :

    xXNicolaXx ha scritto:


    Quindi nella classe passeggero, nome, cognome e numero non devono essere dei vettori ma delle semplici stringhe e interi(per il numero) e devo poi inserirli in un unico array(passeggeri) che verrà stampato su richiesta?
    Sì nome e cognome in Passeggero sono semplici stringhe. Tu eri "costretto" ad usare un vettore di nomi per poter avere una collezione di nomi, uno diverso dall'altro ma, senza l'oggetto passeggero, per poter recuperare un passeggero dovevi unire questo nome ad un cognome salvato in un array di cognomi (nel corrispondente indice).
    Questo come dicevo ha ben poco senso, gli oggetti esistono apposta per evitare questi giri (questa è proprio la base del linguaggio).
    Tu hai bisogno di avere diversi passeggeri, ma ogni passeggero ha un solo nome, un solo cognome etc (ovviamente nomi composti compongono un singolo nome, separato da spazi o altro, non avrai mai bisogno di salvare un array di nomi per un singolo passaggero, o quantomeno è una situazione estremissima)...

    Quindi in una certa classe avrai un array di passeggeri (o una lista, una mappa, qualsiasi altra struttura dati), ogni Passeggero invece conterrà al proprio interno le singole informazioni.

    xXNicolaXx ha scritto:


    Il toString() non l'ho mai usato..ho dato un occhiata veloce adesso..in pratica mi trasforma ad esempio un intero in una stringa? [...]
    Per quanto riguarda il toString(), è un concetto piuttosto semplice di per sè, ma per capire bene come sfruttarlo dovresti avere presenti altri concetti come ereditarietà, poliformismo etc. che forse adesso non conosci ancora.

    Cercati qualche buona guida su come usare il toString() e magari su quei concetti a cui facevo riferimento (se non hai già un buon libro), ad esempio questo è il primo risultato su google: .
    Leggendo capirai che toString() non "trasforma" un oggetto in una stringa, ma viene usato per fornire una rappresentazione testuale di un oggetto (che ad esempio viene richiamata in automatico quando provi a stampare un oggetto a video).

    Prova questo piccolo esempio usando questo codice (completa tu le informazioni mancanti di Passeggero) :
    public class Test
    {
    	public static void main(String args[]) {
    		PasseggeroSenzaToString p = new PasseggeroSenzaToString("Pippo", "Baudo");
    		// Questo print fornisce il toString ereditato da Object, è poco informativo
    		System.out.println(p);
    		/*Sei costretto in questo caso a "comporre" tu le informazioni di interesse, in qualsiasi punto del codice dove vuoi reperire le informazioni di un passeggero, ad esempio: */
    		System.out.println("Passeggero : " + p.getNome() + p.getCognome());
    		System.out.println();
    		// E' molto meglio questo approccio :
    		Passeggero p2 = new Passeggero("Pippo", "Baudo");
    		/* Come vedi e' la stessa cosa passare a System.out.print() l'oggetto o richiamarci in modo esplicito il toString() sopra (sempre che l'oggetto non sia null, nel qual caso il secondo comando lancerà una NullPointerException). */
    		System.out.println(p2);
    		System.out.println(p2.toString());
    	}
    }
    class PasseggeroSenzaToString
    {
    	private String nome, cognome;
    	public PasseggeroSenzaToString(String nome, String cognome) {
    		this.nome = nome;
    		this.cognome = cognome;
    	}
    	public String getCognome() {
    		return cognome;
    	}
    	public String getNome() {
    		return nome;
    	}
    }
    class Passeggero
    {
    	private String nome, cognome;
    	public Passeggero(String nome, String cognome) {
    		this.nome = nome;
    		this.cognome = cognome;
    	}
    	public String getCognome() {
    		return cognome;
    	}
    	public String getNome() {
    		return nome;
    	}
    	/* @Override è un'annotazione utile quando ridefinisci un metodo: se il metodo non è effettivamente l'override di un metodo ereditato dalla
    	superclasse (ad esempio hai scritto per sbaglio una minuscola al posto di una maiuscola) il compilatore ti segnala l'errore */
    	@Override public String toString() {
    		// Qui puoi ritornare una stringa nella forma che preferisci !
    		return "Passeggero : " + nome + " " + cognome;
    	}
    }

    xXNicolaXx ha scritto:


    Questo metodo mi serve per stampare quindi il vettore con i 3 campi(nome,cognome e numero) insieme?
    Vedi sopra, non si parla più di vettore con tre campi, ma di un Oggetto che contiene all'interno i propri campi e i propri metodi.
    Ridefinire toString() non è l'unico modo di fare la stampa a video, puoi crearti qualsiasi metodo che lo faccia, nel codice sopra puoi inserire la concatenazione dei vari get all'interno di un metodo (come il tuo stampa()), ma è molto più comodo seguire il consiglio di ridefinire toString(), che tra l'altro è utile in molti altri ambiti.

    xXNicolaXx ha scritto:


    edit: altra cosa..l'input da tastiera del nome e del cognome lo devo fare dalla classe registrazioni oppure dalla classe passeggero?
    Questo dipende dal design delle classi, ma quasi tutti sconsigliano fortemente di leggere da Scanner all'interno del costruttore di una classe come Passeggero. Meglio farlo dall'esterno e poi istanziare il Passeggero con tutti i dati letti, questo tra l'altro ti consente di gestire prima eventuali errori senza dover lanciare eccezioni etc.
  • Re: Aiutino per richiamare metodi di altre classi?

    Grazie mille per esserti preso il tempo di scrivermi un codice di esempio. E' dalle 9 di stamattina fino ad adesso che sto cercando di capire questi concetti basilari. Il libro che sto leggendo è di walter savitch "programmazione di base e avanzata con java".
    Ci sono alcune cose che proprio non riesco a capire e a cui su internet non riesco a trovare risposta(sicuro c'è, ma io non la capisco).
    Nel tuo programma ho visto che hai usato i metodi getNome e getCognome. In questo caso perchè il metodo setNome e setCognome non va scritto? Si usa solo quando l'input viene dato dal main e non da tastiera o non c'entra nulla?
    poi.. nel main hai scritto
    PasseggeroSenzaToString p = new PasseggeroSenzaToString("Pippo", "Baudo");
    In questo modo tu hai già dato il nome Pippo Baudo al passeggero. Nel caso però li debba inserire io da tastiera, ho visto che non posso lasciare vuote le parentesi dove appunto hai scritto ("pippo","baudo"), perchè il costruttore richiede che li si passi la stringa nome e la stringa cognome. Come faccio quindi? Devo fare un costruttore vuoto(che è che quello di default di java, quindi ha senso che lo faccio?)
    Solamente se hai tempo e voglia, ti andrebbe di farmi un brevissimo esempio solo con l'inserimento da tastiera di più nomi inseriti uno alla volta, in modo che poi posso stampare tutto il vettore(e anche questo che non capisco). Solo con il nome, lasciando stare cognome, numero ecc..quindi tipo
    "inserisci nome"
    input tastiera
    "Inserirne un altro?"
    si
    "inserisci nome" input tastiera"
    input tastiera
    "inserirne un altro?"
    no
    stampa del vettore contenente i nomi

    Credo che con un esempio del genere potrei capire come fare poi ad aggiungere i cognomi e il numero..
    Ripeto,solamente se hai voglia e tempo. Intanto ti ringrazio già moltissimo per l'aiuto che mi hai dato
  • Re: Aiutino per richiamare metodi di altre classi?

    Mi hai anticipato ancora
    Intanto posto comunque questa risposta al tuo precedente messaggio, così puoi già leggere

    xXNicolaXx ha scritto:


    Ho provato a rifare il codice ragazzi..ho aggiunto la classe passeggeri [...]
    Creare una classe Passeggeri come quella non fa altro che aumentare la tua confusione. Non è una buona pratica gestire in quel posto la lettura dei dati da passare poi a un costruttore. La tua entità di base è il singolo Passeggero, quindi crea una classe Passeggero (nota il singolare, è molto più chiaro).
    Nella classe puoi definire quanti costruttori vuoi, in molti casi ha senso che tu possa costruire un oggetto senza fornire tutti i parametri possibili, assegnando dei valori di default, ma in questo caso lo trovo poco utile. Anche il numero io non lo fornirei in ingresso, perché tu vuoi avere un numero distinto per ogni Passeggero. Visto che per ora sembri avere qualche dubbio generale segui il mio consiglio iniziale : mantieni una variabile statica in Passeggero che si incrementa ad ogni passeggero creato. Se non ti è chiaro perché la variabile deve essere statica e non di istanza, questo è un concetto che devi assolutamente comprendere quanto prima, quindi fermati un attimo per chiarire la questione.

    Per il resto va bene l'uso dei metodi get (è standard), a me personalmente invece non piace un metodo setPasseggero che modifichi tutte le informazioni assieme (tra l'altro se vuoi che il numero sia progressivo potrebbe non aver senso poterlo modificare). Ovviamente non è un errore avere un metodo come quello, ma per ora magari usa dei metodi setter specifici per ogni campo, sempre che nel tuo contesto di riferimento abbia senso poter modificare il nome, il cognome, etc. (se non deve essere possibile potresti dichiarare le variabili come final, ma questo apre un discorso più ampio).

    Ultima cosa, sempre per chiarezza, a me piace maggiormente non richiamare i metodi set all'interno dei costruttori ma assegnare direttamente i valori, ovviamente non è così fondamentale e in altri casi passare per i metodi set potrebbe essere utile.

    Quindi la tua classe Passeggeri, quantomeno per ora, io la scriverei in questo modo (poi in base alle tue esigenze puoi aggiungere la variabile risposta e scegliere se inserire o meno altri metodi set/ altri costruttori) :
    
    package aeroporto;
    public class Passeggero
    {
        private static int numeroPasseggeri = 0; // importante capire perchè questo campo è static !!
        private String nome, cognome;
        private int numero;
      
    	public Passeggero (String nome, String cognome) {
    		this.nome = nome;
    		this.cognome = cognome;
    		this.numero = numeroPasseggeri;
    		numeroPasseggeri ++; // se inserisci altri costruttori, devi inserire questa istruzione anche lì, oppure passare per questo costruttore
    	}
    
    	/* public void stampaPasseggeri() {
    		System.out.println("Nome : " +getNome());
    		System.out.println("Numero : " +getNumero());
    	} 
    	*/
    
    	public String getCognome() {
    		return cognome;
    	}
    	
    	public String getNome() {
    		return nome;
    	}
    
    	public int getNumero() {
    		return numero;
    	}
    	
    	public int getNumeroPasseggeri() {
    		return numeroPasseggeri;
    	}
    	
    	public void setCognome(String nuovoCognome) {
    		cognome = nuovoCognome;
    	}
    	
    	public void setNome(String nuovoNome) {
    		nome = nuovoNome;
    	}
    	// Per ora non ho inserito la possibilità di cambiare numero a un passeggero ...
    }
    
    Consiglio: scegli tu come completare la classe con eventuali altri set poi, se hai capito come usare il toString(), sostituisci quel metodo stampaPasseggeri() che ho commentato con una implementazione di toString().
    Infine prova a riscrivere la classe Registrazioni considerando che dovresti fare in quel posto la lettura dallo scanner.

    Fatto questo sarà tutto più chiaro e anche stampare il vettore di oggetti Passeggero sarà molto più semplice, poi se ci sono problemi/non sei d'accordo su qualcosa, scrivi pure qui

    [EDIT] Modificato il costruttore di passeggero, avevo scritto una boiata colossale...
  • Re: Aiutino per richiamare metodi di altre classi?

    Ansharja ha scritto:


    Mi hai anticipato ancora
    Intanto posto comunque questa risposta al tuo precedente messaggio, così puoi già leggere

    xXNicolaXx ha scritto:


    Ho provato a rifare il codice ragazzi..ho aggiunto la classe passeggeri [...]
    Creare una classe Passeggeri come quella non fa altro che aumentare la tua confusione. Non è una buona pratica gestire in quel posto la lettura dei dati da passare poi a un costruttore. La tua entità di base è il singolo Passeggero, quindi crea una classe Passeggero (nota il singolare, è molto più chiaro).
    Nella classe puoi definire quanti costruttori vuoi, in molti casi ha senso che tu possa costruire un oggetto senza fornire tutti i parametri possibili, assegnando dei valori di default, ma in questo caso lo trovo poco utile. Anche il numero io non lo fornirei in ingresso, perché tu vuoi avere un numero distinto per ogni Passeggero. Visto che per ora sembri avere qualche dubbio generale segui il mio consiglio iniziale : mantieni una variabile statica in Passeggero che si incrementa ad ogni passeggero creato. Se non ti è chiaro perché la variabile deve essere statica e non di istanza, questo è un concetto che devi assolutamente comprendere quanto prima, quindi fermati un attimo per chiarire la questione.

    Per il resto va bene l'uso dei metodi get (è standard), a me personalmente invece non piace un metodo setPasseggero che modifichi tutte le informazioni assieme (tra l'altro se vuoi che il numero sia progressivo potrebbe non aver senso poterlo modificare). Ovviamente non è un errore avere un metodo come quello, ma per ora magari usa dei metodi setter specifici per ogni campo, sempre che nel tuo contesto di riferimento abbia senso poter modificare il nome, il cognome, etc. (se non deve essere possibile potresti dichiarare le variabili come final, ma questo apre un discorso più ampio).

    Ultima cosa, sempre per chiarezza, a me piace maggiormente non richiamare i metodi set all'interno dei costruttori ma assegnare direttamente i valori, ovviamente non è così fondamentale e in altri casi passare per i metodi set potrebbe essere utile.

    Quindi la tua classe Passeggeri, quantomeno per ora, io la scriverei in questo modo (poi in base alle tue esigenze puoi aggiungere la variabile risposta e scegliere se inserire o meno altri metodi set/ altri costruttori) :
    
    package aeroporto;
    public class Passeggero
    {
        private static int numero; // importante capire perchè questo campo è static !!
        private String nome, cognome;
      
    	public Passeggero (String nome, String cognome) {
    		this.nome = nome;
    		this.cognome = cognome;
    		numero ++; // se inserisci altri costruttori, devi inserire questa istruzione anche lì, oppure passare per questo costruttore
    	}
    
    	/* public void stampaPasseggeri() {
    		System.out.println("Nome : " +getNome());
    		System.out.println("Numero : " +getNumero());
    	} 
    	*/
    
    	public String getCognome() {
    		return cognome;
    	}
    	
    	public String getNome() {
    		return nome;
    	}
    
    	public int getNumero() {
    		return numero;
    	}
    	
    	public void setCognome(String nuovoCognome) {
    		cognome = nuovoCognome;
    	}
    	
    	public void setNome(String nuovoNome) {
    		nome = nuovoNome;
    	}
    	// Per ora non ho inserito la possibilità di cambiare numero a un passeggero ...
    }
    
    Consiglio: scegli tu come completare la classe con eventuali altri set poi, se hai capito come usare il toString(), sostituisci quel metodo stampaPasseggeri() che ho commentato con una implementazione di toString().
    Infine prova a riscrivere la classe Registrazioni considerando che dovresti fare in quel posto la lettura dallo scanner.

    Fatto questo sarà tutto più chiaro e anche stampare il vettore di oggetti Passeggero sarà molto più semplice, poi se ci sono problemi/non sei d'accordo su qualcosa, scrivi pure qui
    Grazie mille ancora per le continue risposte..
    allora, quindi il metodo set serve per modificare la variabile che in questo caso è la stringa nome e/o cognome, giusto? La classe passeggero è quindi completa come l'hai scritta tu. Non so se non ho capito io e chiedo scusa in anticipo, ma con quel metodo stampa "System.out.println("Nome : " +getNome());" mi va a stampare l'ultimo nome inserito..quindi se ad esempio metto come primo nome pippo e poi chiedo di inserirne un altro e digito baudo, lui quando chiederò la stampa mi fa vedere solamente baudo..forse perchè appunto devo poi inserirlo in un vettore che contiene nome+cognome? Questa cosa si fa come ho fatto nell'ultimo codice da me postato, ovvero mettendo nella classe registrazioni questo:
    public Passeggeri[] persone;
    In questo modo creo un vettore persone che contiene i parametri passati dentro il costruttore della classe passeggeri? Nelle parentesi quadre dopo Passeggeri, devo aggiungere "nome, cognome" o sto proprio sbagliando tutto?
    Scusami, ma sto facendo una fatica a capire queste cose basi..
  • Re: Aiutino per richiamare metodi di altre classi?

    Allora lo fai apposta a scrivere sempre prima di me

    Ora non ho tempo per leggere il tuo ultimo messaggio, intanto ti spedisco questo, prova a seguire tutte le indicazioni, se ci sono dubbi/perplessità o qualsiasi altra cosa ci risentiamo dopo

    xXNicolaXx ha scritto:


    Nel tuo programma ho visto che hai usato i metodi getNome e getCognome. In questo caso perchè il metodo setNome e setCognome non va scritto? Si usa solo quando l'input viene dato dal main e non da tastiera o non c'entra nulla?
    Prima di tutto tieni presente che non esiste un unico modo di fare le cose, cerco di seguire il più possibile quello che ho imparato nelle guide lette e nei forum online .
    I metodi set possono tranquillamente essere aggiunti, infatti nell'ultimo messaggio li ho inseriti. Il fatto è che una classe cerca di rappresentare il più fedelmente possibile la realtà di interesse. Quindi nel tuo contesto ha senso che un Passeggero possa cambiare nome? Magari la risposta può essere sì anche solo perché qualcuno può aver sbagliato a scrivere un dato in ingresso, e vuoi poterlo modificare senza creare un nuovo Passeggero.

    Ti butto solo lì il dubbio, poi dipende da te e da quello che ti dirà il professore o chi comunque ne sa più di me. Solo nel caso del numero però, io non lascerei la possibilità di settarlo a piacere, la cosa è rischiosa e dovresti quanto meno controllare il vincolo di unicità (se vuoi che il numero identifichi univocamente un passeggero), e la cosa non è banale.

    xXNicolaXx ha scritto:



    poi.. nel main hai scritto
    PasseggeroSenzaToString p = new PasseggeroSenzaToString("Pippo", "Baudo");
    In questo modo tu hai già dato il nome Pippo Baudo al passeggero. Nel caso però li debba inserire io da tastiera, ho visto che non posso lasciare vuote le parentesi dove appunto hai scritto ("pippo","baudo"), perchè il costruttore richiede che li si passi la stringa nome e la stringa cognome. Come faccio quindi? Devo fare un costruttore vuoto(che è che quello di default di java, quindi ha senso che lo faccio?)
    Esatto, hai capito la questione del costruttore vuoto. In realtà riscrivere un costruttore vuoto può avere senso, perché quello di default non inizializza tutti i campi (gli oggetti come String rimangono NULL se non sono inizializzati nel costruttore o nella definizione, mentre i tipi primitivi come int, char etc. sono inizializzati ai propri valori di default, perché non possono essere NULL).
    Ma l'importante è che un costruttore vuoto avrebbe senso se tu potessi creare un passeggero senza parametri, ad esempio nel costruttore vuoto inizializzi tu il nome a "Mario" e il cognome a "Rossi". In questo caso io non lo farei.

    xXNicolaXx ha scritto:


    Solamente se hai tempo e voglia, ti andrebbe di farmi un brevissimo esempio solo con l'inserimento da tastiera di più nomi inseriti uno alla volta [...]
    Questo sarebbe meglio che provassi a scriverlo tu, poi se non riesci ti aiutiamo.
    Tieni presente che una volta creato uno scanner puoi usare quante volte vuoi il metodo nextLine(), quindi nel tuo metodo basterà usare due volte il nextLine() e salvare la stringa in due variabili nome e cognome.
    Ovviamente prima di chiamare il nextLine() puoi stampare a video uno o più messaggi per aiutare l'utente a capire cosa il programma si aspetta di leggere, ma non è fondamentale.
    Una volta che hai queste due varabili nome e cognome puoi fare tutti i dovuti controlli (ad esempio vuoi che siano lunghi almeno tre caratteri, o vuoi che uno non possa chiamarsi "Pippo", o qualsiasi cosa ti venga in mente), solo se i controlli hanno successo (ovviamente per ora puoi anche non fare alcun controllo, ma questa è la logica di leggere prima i dati, e poi utilizzarli) crei un nuovo passeggero passando le due stringhe lette.
    In seguito puoi generalizzare la cosa e leggere N diverse informazioni da tastiera, non fa alcuna differenza.

    Ti consiglio di creare il metodo che crei un solo passeggero per ora, seguendo i passi sopra, poi sarà semplice creare un ciclo che simuli un menù e chieda all'infinito di inserire un nuovo passeggero, stampare tutti quelli creati, o fare qualsiasi altra cosa.

    Intanto prova ad arrivare qui
  • Re: Aiutino per richiamare metodi di altre classi?

    Allora...finalmente, dopo 6 ore di grazie ai tuoi consigli è uscito qualcosa. Ho fatto quello che mi hai detto alla fine del tuo ultimo messaggio, ovvero provare solamente a inserire un passeggero con il suo nome, il suo cognome e il numero viene assegnato automaticamente partendo da "0". Ora, sono convinto che il codice in parte è sbagliato anche se funziona..in ogni caso lo posto e poi sotto pongo due domande

    Classe contenente il main:
    package aereoporto;
    
    
    public class Aereoporto {
    
       
        public static void main(String[] args) {
            
            Registrazione r = new Registrazione();
            r.registra();
        }
        
    }
    Classe Registrazione:
    
    
    package aereoporto;
    
    import java.util.Scanner;
    
    public class Registrazione {
        Passeggero pass = new Passeggero("", "", 0);
        Scanner tastiera = new Scanner(System.in);
        
        public void registra(){
            
        System.out.println("Benvenuto! Inserisca il suo nome : ");
        pass.nome = tastiera.nextLine();
        System.out.println("Il nome inserito è : " + pass.nome);
        System.out.println("Inserisca il suo cognome : ");
        pass.cognome = tastiera.nextLine();
        System.out.println("Il cognome inserito è : " + pass.cognome);
        System.out.println("Le è stato assegnato il numero : " + pass.numero);
        stampa();
        }
        public void stampa(){
            System.out.println("Nome : " + pass.getNome());
            System.out.println("Cognome : " + pass.getCognome());
            System.out.println("Numero : " + pass.getNumero());
        }
        
        
        
    }
    
    Classe Passeggero:
    
    package aereoporto;
    
    
    public class Passeggero {
        
        public String nome; 
        public String cognome;
        public int numero;
    
        public Passeggero(String nome, String cognome, int numero) {
            this.nome = nome;
            this.cognome = cognome;
            this.numero = numero;
        }
    
        public String getNome() {
            return nome;
        }
    
        public String getCognome() {
            return cognome;
        }
    
        public int getNumero() {
            return numero;
        }
        
        
        
    }
    Ora le due domande...
    1) per poter accedere alle variabili della classe Passeggero (nome, cognome e numero) le ho dovute impostare come public, perchè con private non mi ci faceva accedere. Cosa si usa per appunto poter accedere a una variabile privata?
    2) Nel metodo stampa io ho scritto
    
    System.out.println("Nome : " + pass.getNome);
    
    Ma ho visto che funzionava pure così:
    
    System.out.println("Nome : " + nome);
    
    Qual'è la differenza, e quale dei è meglio usare?
    Dai che forse piano piano sto iniziando a capire qualcosa
  • Re: Aiutino per richiamare metodi di altre classi?

    Innanzitutto attento all'EDIT che avevo inserito nel messaggio con il codice, avevo scritto di fretta e inserito un errore macroscopico...

    Riprendo da dove ero rimasto con le risposte :

    xXNicolaXx ha scritto:



    [...] allora, quindi il metodo set serve per modificare la variabile che in questo caso è la stringa nome e/o cognome, giusto? La classe passeggero è quindi completa come l'hai scritta tu.
    Ok per il set. Nota che modificare le variabili con il metodo set è il modo più utilizzato per una lunga serie di motivi, non l'unico.
    Non ha molto invece senso parlare di classe completa o meno, come fai a definire quando una classe è completa? Se hai i metodi getter e setter per ogni campo (quelli per cui vale la pena prevederli) e hai dei costruttori sensati, sei già a buon punto, ma puoi sempre aggiungere nuove funzionalità, ridefinire toString() è un esempio, ma potresti anche ridefinire equals() o aggiungere quanti e quali metodi vuoi... In questo caso direi che per ora è accettabile (ma considera i cambiamenti che avevo fatto).

    xXNicolaXx ha scritto:


    Non so se non ho capito io e chiedo scusa in anticipo, ma con quel metodo stampa "System.out.println("Nome : " +getNome());" mi va a stampare l'ultimo nome inserito..quindi se ad esempio metto come primo nome pippo e poi chiedo di inserirne un altro e digito baudo, lui quando chiederò la stampa mi fa vedere solamente baudo..forse perchè appunto devo poi inserirlo in un vettore che contiene nome+cognome?
    No, questo non è esatto. Stai continuando a focalizzarti su quell' "ultimo nome inserito", ma non è assolutamente così. Il metodo getNome() è definito nella classe Passeggero, e può essere richiamato su qualsiasi oggetto di quella classe. Continui a confondere oggetti con array, ma questo è un punto cruciale. L'oggetto Passeggero contiene al proprio interno i campi nome,cognome,numero e i metodi sopra elencati. Non è un vettore che contiene nome+cognome, questi dati sono variabili di Passeggero.

    Poi se vuoi le tue istanze di Passeggero possono essere inserite in un vettore, ma i metodi definiti su Passeggero li puoi richiamare su qualunque passeggero, che sia contenuto in un array (in qualsiasi posizione), in un'altra struttura, o anche creato sul momento (come facevo nella classe Test).

    xXNicolaXx ha scritto:


    public Passeggero[] persone;
    In questo modo creo un vettore persone che contiene i parametri passati dentro il costruttore della classe passeggeri? Nelle parentesi quadre dopo Passeggeri, devo aggiungere "nome, cognome" o sto proprio sbagliando tutto?
    In questo modo crei un vettore di oggetti Passeggero (ora la classe si chiama in questo modo, non più Passeggeri) : ogni singola elemento del vettore è un oggetto Passeggero, che può essere istanziato con i parametri che passi al costruttore di Passeggero. Nelle parentesi quadre non devi aggiungere proprio nulla, quella è solo la dichiarazione di un array.

    Passando ora al tuo ultimo messaggio :

    Fino ad Aeroporto nulla di particolare, per ora va bene, poi potrai decidere come/dove organizzare il tuo ciclo.

    La classe Registrazione e Passeggero invece non vanno bene!

    In Passeggero le variabili non dovresti tenerle public, ma mantenerle private come prima e accedere a quei campi con i metodi get (è a quello che servono i metodi getXXX()).
    Poi hai reinserito un costruttore che setta anche la variabile numero, se leggi il messaggio scritto in precedenza spiegavo che questo è pericoloso (dovresti controllare il vincolo di unicità). Riprendi il codice che ho modificato, quello con la variabile numeroPasseggeri.
    La variabile statica che si autoincrementa è il metodo migliore (a questo punto della tua preparazione perlomeno) per assegnare automaticamente il numero al passeggero, in modo che non ci siano errori di alcun genere quando passi tu il numero via costruttore.

    Infine in Passeggero dovresti aggiungere il metodo toString() come dicevo in precedenza. Non è obbligatorio, ma quanto fai in Registrazione dimostra che non hai ancora capito bene il concetto (vedi sotto).

    In Registrazione infatti dichiari un Passeggero pass (al cui costruttore passi stringhe vuote per il nome e il cognome). Questo Passeggero è totalmente inutile !
    Le stringhe che leggi in registra() dallo scanner non devono modificare il nome di un Passeggero già esistente (pass), devono essere memorizzate per poi creare un nuovo Passeggero con i dati che hai letto!
    In futuro potrai avere un metodo che modifica tali informazioni (con i metodi setXXX(), non utilizzando variabili pubbliche), ma per ora occupati di leggere le stringhe e creare il nuovo Passeggero passando al costruttore (è qui che devi usare la keyword new) le stringhe che hai memorizzato in due variabili temporanee.

    Infine il metodo stampa scritto così non va bene. Se non vuoi ridefinire toString() in Passeggero (ma dovresti), e vuoi mantenere un metodo di stampa in Registrazione, questo metodo deve quantomeno ricevere in ingresso il Passeggero da 'stampare' e invocare su quella istanza i metodi getXXX() che restituiscono i dati.
    Tu invece in stampa() stai scrivendo a video le informazioni del Passeggero pass, ma invocando stampa() dopo aver creato un altro Passeggero continuerai a vedere sempre e solo le informazioni di pass.

    xXNicolaXx ha scritto:


    Ora le due domande...
    1) per poter accedere alle variabili della classe Passeggero (nome, cognome e numero) le ho dovute impostare come public, perchè con private non mi ci faceva accedere. Cosa si usa per appunto poter accedere a una variabile privata?
    2) Nel metodo stampa io ho scritto
    
    System.out.println("Nome : " + pass.getNome);
    
    Ma ho visto che funzionava pure così:
    
    System.out.println("Nome : " + nome);
    
    Qual'è la differenza, e quale dei è meglio usare?
    Dai che forse piano piano sto iniziando a capire qualcosa
    Alla prima domanda ho risposto sopra. Le variabili sono tenute private volontariamente per non potervi accedere dall'esterno. Per accedere si usano appunto i metodi get.

    Per la seconda domanda la differenza è semplice: pass.getNome() restituisce la stringa nome dell'oggetto pass (di tipo Passeggero).
    Se stampi invece la variabile nome, la variabile deve essere prima di tutto definita! Nella classe Registrazione non hai una variabile nome definita come campo, quindi se non la definisci neanche nel metodo stampa() riceverai un errore in compilazione, perché il compilatore non sa a cosa ti stai riferendo!
  • Re: Aiutino per richiamare metodi di altre classi?

    In Registrazione infatti dichiari un Passeggero pass (al cui costruttore passi stringhe vuote per il nome e il cognome). Questo Passeggero è totalmente inutile !
    Le stringhe che leggi in registra() dallo scanner non devono modificare il nome di un Passeggero già esistente (pass), devono essere memorizzate per poi creare un nuovo Passeggero con i dati che hai letto!

    Ecco, è proprio questo che non riesco a capire. Se non dichiaro un oggetto(pass) come faccio a richiamare i metodi di un altra classe?(in questo caso cosa devo richiamare quindi, il get o il costruttore?)
    Per quanto riguarda la seconda frase del quote invece..anche lì, non capisco come faccio a memorizzarle senza sovrascriverle. Ho rifatto la classe passeggero per il momento..dimmi se adesso va bene. Per quella registrazione invece non capisco proprio come fare
    
    package aereoporto;
    
    
    public class Passeggero {
        
        private String nome; 
        private String cognome;
        private int numero;
        private static int numeroPasseggeri = 0;
    
        public Passeggero(String nome, String cognome) {
            this.nome = nome;
            this.cognome = cognome;
            this.numero = numeroPasseggeri;
            numeroPasseggeri++;
            
        }
        public void stampaPasseggeri(){
            System.out.println("Nome : " + getNome() + "Cognome : " + getCognome() + "Numero" + getNumero());
        }
    
        public String getNome() {
            return nome;
        }
    
        public String getCognome() {
            return cognome;
        }
    
        public int getNumero() {
            return numero;
        }
        
        
        
    }
    
    ps. se hai del materiale online che spieghi bene questa cosa che sto affrontando e riesci a linkarmelo, lo leggo volentieri..
  • Re: Aiutino per richiamare metodi di altre classi?

    xXNicolaXx ha scritto:


    In Registrazione infatti dichiari un Passeggero pass (al cui costruttore passi stringhe vuote per il nome e il cognome). Questo Passeggero è totalmente inutile !
    Le stringhe che leggi in registra() dallo scanner non devono modificare il nome di un Passeggero già esistente (pass), devono essere memorizzate per poi creare un nuovo Passeggero con i dati che hai letto!

    Ecco, è proprio questo che non riesco a capire. Se non dichiaro un oggetto(pass) come faccio a richiamare i metodi di un altra classe?(in questo caso cosa devo richiamare quindi, il get o il costruttore?)
    Esatto, se non dichiari un oggetto non riesci a richiamarci metodi sopra come il get (a meno che un metodo non sia statico, in quel caso lo puoi richiamare solo con il nome della classe, ma questo per ora non ti interessa...).
    Tuttavia il costruttore di una classe non richiede che esista già un oggetto su cui essere richiamato: è proprio quello il metodo per costruirlo da zero!
    Quindi per poter istanziare un nuovo oggetto non hai bisogno di nessun oggetto preesistente, ti basta scrivere ad es. new Passeggero (/*argomenti*/). Questo lo puoi fare in qualsiasi classe, purché la classe e il costruttore della classe siano "visibili" nel punto in cui provi a fare la creazione (la questione della visibilità di un metodo/variabile/classe è un altro argomento da approfondire).

    xXNicolaXx ha scritto:


    Per quanto riguarda la seconda frase del quote invece..anche lì, non capisco come faccio a memorizzarle senza sovrascriverle.


    Immagina di avere il metodo registra in Registrazione scritto in questo modo (non te lo faccio completo apposta, è molto meglio se ci arrivi tu ) :
    
    public void registra() {        
    	System.out.println("Benvenuto! Inserisca il suo nome : ");
    	String nome = "Pippo";
    	System.out.println("Inserisca il suo cognome : ");
    	String cognome = "Baudo";
    	Passeggero passeggero = new Passeggero(nome, cognome);
    }
    
    Ti è chiaro cosa fa questo metodo ? Le stringhe nome e cognome in questo caso le inserisco direttamente io, poi le passo al costruttore di Passeggero che crea un nuovo Passeggero con quel nome e quel cognome. Tu vuoi fare una cosa simile, ma nome e cognome vuoi leggerle dallo Scanner: è in quel punto che devi assegnare a nome e cognome ciò che leggi da scanner!

    Altra cosa: cosa succede di quelle variabili nome, cognome, passeggero che hai definito dentro al metodo, una volta che il metodo termina ? Nulla!
    Sono locali al metodo, quindi una volta usciti dal metodo, dopo aver creato il nuovo passeggero, non sono più raggiungibili in nessun modo se non vengono assegnate a qualcosa di esistente!

    Quindi se tu richiamassi il metodo registra() un'altra volta non staresti sovrascrivendo quelle variabili, le stai solo ricreando da zero localmente al metodo. Diverso sarebbe se nome e cognome fossero già definite in Registrazione, e dentro a registra facessi solo l'assegnazione (quindi senza riscrivere String nome = ... , ma solo con nome = ...), in questo caso le staresti sovrascrivendo.

    Ma questo ha poca importanza, perché al costruttore viene passato di volta il valore "corrente" che hanno quelle variabili, una volta che avrai sostituito "Pippo" e "Baudo" con ciò che leggi da scanner, creerai oggetti Passeggero con nomi e cognomi diversi l'uno dall'altro (a meno di non reinserire gli stessi dati ovviamente).

    Quindi questo è quello che devi fare. Solo questo ? In realtà no. Come detto, quel passeggero che crei non è raggiungibile da fuori quel metodo , quindi tu in seguito vorrai aggiungerlo ad un array (o un'altra struttura dati) definito in Registrazione.
    Ho rifatto la classe passeggero per il momento..dimmi se adesso va bene. [...]
    
    package aereoporto;
    public class Passeggero {
        
        private String nome; 
        private String cognome;
        private int numero;
        private static int numeroPasseggeri = 0;
    
        public Passeggero(String nome, String cognome) {
            this.nome = nome;
            this.cognome = cognome;
            this.numero = numeroPasseggeri;
            numeroPasseggeri++;
            
        }
        public void stampaPasseggeri(){
            System.out.println("Nome : " + getNome() + "Cognome : " + getCognome() + "Numero" + getNumero());
        }
    
        public String getNome() {
            return nome;
        }
    
        public String getCognome() {
            return cognome;
        }
    
        public int getNumero() {
            return numero;
        }   
        
    }
    
    Fin qui è più o meno quello che avevo scritto io. Il metodo stampaPasseggeri (perchè Passeggeri?, ricordati che la classe ha le informazioni di un singolo passeggero) può tranquillamente essere abolito se inserisci il toString() come consigliato, basta che ti guardi il mio esempio precedente, e al posto di nome, ritorni quella stringa che ora stampi a video (con la concatenazione di nome, cognome e numero).
    All'interno di Passeggero puoi tranquillamente usare i campi, non serve passare per i metodi getXXX(), sono privati solo per chi è all'esterno della classe, ma comunque non è un errore.
    ps. se hai del materiale online che spieghi bene questa cosa che sto affrontando e riesci a linkarmelo, lo leggo volentieri..
    Di materiale ne trovi a tonnellate, non ho qualche cosa specifica, io ho letto le guide java presenti sia su questo forum sia in html.it, ma non ricordo quanto abbondantemente trattino questi argomenti. Per il resto ho frequentato un corso di tre mesi e imparato sbattendo la testa su esercizi come questo e leggendo molto online, puoi riuscirci tranquillamente anche tu!
  • Re: Aiutino per richiamare metodi di altre classi?

    Non capisco una cosa però..
    quando nella classe Registrazione istanzio un nuovo oggetto cosi:
    Passeggero p = new Passeggero();
    devo passare dei valori dentro le parentesi? Perchè ho provato qualsiasi cosa ma da sempre errore..quindi presumo debba lasciare vuoto.
    Poi...ho provato a fare l'input in due modi:
    primo modo:
    System.out.println("Benvenuto! Inserisca il suo nome : ");
        String nome = tastiera.nextLine();
        System.out.println("Il nome inserito è " + nome);
        
        
        System.out.println("Inserisca il suo cognome : ");
        String cognome = tastiera.nextLine();
        System.out.println("Il cognome inserito è " + cognome);
        
        p.toString();
    In questo modo mi stampa subito dopo il nome e il cognome che digito, ma quando poi richiamo il metodo toString, non compare niente a video
    Il metodo toString l'ho fatto cosi:
    @Override
    public String toString(){
            return "Passeggero : " + nome + " " + cognome;
        }
    Se faccio cosi:
    System.out.println("Benvenuto! Inserisca il suo nome : ");
        String nome = tastiera.nextLine();
        System.out.println("Il nome inserito è " + nome);
        
        
        System.out.println("Inserisca il suo cognome : ");
        String cognome = tastiera.nextLine();
        System.out.println("Il cognome inserito è " + cognome);
        
        p.stampaPasseggero()
    dove stampaPasseggero è uguale a come l'ho scritto nel messaggio precedente, allora dopo aver inserito nome e cognome, mi stampa:
    Nome : null Cognome : null Numero : 0
    La classe passeggero è giusta? devo lavorare solo su Registrazione e capire li dove sbaglio?
    Continuo a ringraziarti per la pazienza che stai mostrando
    EDIT: sbagliavo io..istanziavo l'oggetto "p" fuori dal metodo..mettendolo dentro effettivamente mi fa inserire i parametri nome e cognome. Però il metodo toString continua a non stampare..dove sbaglio?
  • Re: Aiutino per richiamare metodi di altre classi?

    Scrivo un nuovo messaggio per segnalarti l'edit dell'ultimo abbastanza importante
Devi accedere o registrarti per scrivere nel forum
40 risposte