Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    1,085

    primi passi .. 'costruttore'

    Ciao,
    mi stò avvicinando a Java .. e i problemi di comprensione si fanno avanti ..
    prima questione: 'costruttori'
    partendo dall'esempio che trovo nella guida trovata nel sito ...

    codice:
           class persone                                     
           {                                                 
             // Proprietà                                    
             public int annodinascita;                       
             public String Cognome=new String();             
                                                                                                         
             // Costruttori                                  
             public persone(int annonascita)                 
             {                                               
               this("Non Conosco");                          
               this.annodinascita = annonascita;             
             }                                               
             
             public persone(String Cognome)                  
             {                                               
               this(0);                                      
               this.Cognome = Cognome;                       
             }                                               
                                                             
             public persone(int annonascita , String Cognome)
             {                                               
               annodinascita = annonascita;                  
               this.Cognome = Cognome;                       
             }                                               
                                                             
             // Metodo che calcola l'età del soggetto        
             public int calcolaeta (int annoattuale)         
             {                                               
               return (annoattuale - annodinascita);         
             }                                               
           }
    mi sembra di aver capito che il costruttore ha la funzione di inizializzare gli attributi ('annodinascita' e 'Cognome')

    primo attributo: 'annodinascita'

    codice:
             // Costruttori                                  
             public persone(int annonascita)                 
             {                                               
               this("Non Conosco");                          
               this.annodinascita = annonascita;             
             }
    1) mi verrebbe da dire che alla funzione devo passare tra parentesi, il nome dell'attributo 'annodinascita' e non 'annonascita'

    2) in pratica l'inizializzazione (immagino con un valore intero) dove viene fatta ?
    codice:
          prima riga    -> "Non Conosco"  
          seconda riga  -> "annonascita"
    Grazie mille

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315

    Moderazione

    Benvenuto nel forum.
    Ti invito subito a prendere visione del Regolamento interno, in particolare il punto 6 che indica le modalità di posting del codice (uso dei tag CODE, indentazione, ecc).

    Sistemo io il tuo post, se possibile.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    il discorso è abbastanza semplice:
    nel primo costruttore
    codice:
             public persone(int annonascita)                 
             {                                               
               this("Non Conosco");                          
               this.annodinascita = annonascita;             
             }
    viene richiamato alla prima riga il costruttore che prende in input una stringa, per inizializzare con il valore "Non Conosco" l'attributo nome, e successivamente viene inizializzato il valore dell'attributo annodinascita con la variabile ricevuta come parametro.
    Analogamente, nel secondo costruttore
    codice:
             public persone(String Cognome)                  
             {                                               
               this(0);                                      
               this.Cognome = Cognome;                       
             }
    viene inzializzata al data di nascita con il valore 0, richiamando il costruttore che ha un solo parametri di tipo intero, e inizializzato il cognome con la stringa ricevuta in input.

  4. #4
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Il codice che hai riportato ha un problema (e difatti il compilatore se ne accorge e ti segnala un errore): il costruttore che riceve un "int" richiama il costruttore che riceve una "String", e viceversa.
    E' una situazione ricorsiva, che se eseguita porterebbe ad un loop (A chiama B, che chiama A, che chiama B, ecc.). Una soluzione migliore è:

    codice:
           class persone
           {
             // Proprietà
             public int annodinascita;
             public String Cognome=new String();
    
             // Costruttori
             public persone(int annonascita)
             {
               this(annonascita, "Non Conosco");
             }
    
             public persone(String Cognome)
             {
               this(0, Cognome);
             }
    
             public persone(int annonascita , String Cognome)
             {
               annodinascita = annonascita;                  
               this.Cognome = Cognome;                       
             }                                               
                                                             
             // Metodo che calcola l'età del soggetto        
             public int calcolaeta (int annoattuale)         
             {                                               
               return (annoattuale - annodinascita);         
             }                                               
           }
    in cui entrambi i costruttori fanno riferimento a quello che riceve entrambi i parametri.

    Come dici tu, scopo primario dei costruttori è dare un valore di "default" alle variabili di un oggetto appena creato.

    Per risponderti:
    1) ai costruttori devi passare il valore della variabile che vuoi utilizzare per l'inizializzazione che, all'interno del codice, sarà utilizzabile tramite l'identificatore che hai dichiarato (nel tuo caso "annonascita" e "Cognome")

    2) il codice che ti ho postato dovrebbe risponderti da solo: l'inizializzazione avviene nel costruttore "int, String"

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    1,085
    Dico la verità .. non ho capito una mazza !
    Intanto non capisco perchè nel seguente costruttore si metta tra parentesi 'int annonascita' quando la variabile si chiama 'annodinascita' ..

    codice:
           
    // Costruttori                     
    public persone(int annonascita)    
    {                                  
      this(annonascita, "Non Conosco");
    }
    poi ..
    mi sembra di aver capito che con questo codice, in sostanza non stò inizializzando, ma stò assegnando alle variabili (annodinascita e Cognome) altre 2 variabili che verranno valorizzate più avanti nel codice .. (senò non capisco come sia stato inizializzato 'annodinascita' che è un intero).
    è corretto ?
    .. anche se non ne capisco il senso visto che non mi spiego, se così fosse, perchè non posso usare direttamente le variabili originali (annodinascita e Cognome) !?
    .. e questa assegnazione mi verrebbe da dire che avvenga qua:

    codice:
    annodinascita = annonascita;        
    this.Cognome = Cognome;
    e sopratutto .. cosa stò facendo in concreto nei seguenti punti .. ?
    (tra l'altro nel primo caso trovo prima 'annonascita' e poi "Non Conosco", nel secondo trovo prima '0' e poi 'Cognome'.
    codice:
    this(annonascita, "Non Conosco");
    e
    codice:
    this(0, Cognome);
    Se qualcuno mi può illuminare gli sarei molto grato.
    grazie mille

  6. #6
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Allora, vediamo...

    Un oggetto ha (normalmente) una serie di attributi, ovverosia una serie di "sue" variabili il cui insieme di valori in un preciso istante definisce il cosiddetto "stato" dell'oggetto.

    Quando istanzi (cioè crei) un nuovo oggetto Java assegna a queste variabili un valore iniziale di default, ad esempio 0 per gli int, null per le stringhe e ogni altro tipo di oggetto, ecc.
    E' tuttavia una buona pratica di programmazione inizializzare esplicitamente queste variabili il prima possibile, e proprio per questo arrivano in aiuto i costruttori: il loro scopo principale è permettere allo sviluppatore di assegnare un valore iniziale agli attributi dell'oggetto.

    Contestualizzo facendo riferimento al tuo codice.
    Nella tua classe "persone" (che per convenzione consolidata sarebbe meglio chiamare "Persone", con la P maiuscola) hai due attributi:
    annodinascita, di tipo int
    Cognome, di tipo String
    Se non esistessero i costruttori, Java inizializzerebbe le due variabili rispettivamente a 0 e null e tu saresti costretto successivamente a dover (ricordarti di) chiamare un metodo specifico per effettuare il primo assegnamento.
    Tramite i costruttori, invece, questa operazione viene eseguita automaticamente nel momento in cui esegui l'istruzione "new" e crei un nuovo oggetto: diciamo che, in parole povere, se esegui

    codice:
    new persone(1950, "Rossi")
    quello che stai facendo è, insieme, creare un nuovo oggetto e richiamare su di esso il "metodo costruttore" (che devi definirti tu, proprio come hai fatto) che riceve in ingresso un int e una String.
    A questo punto, all'interno delle due variabili "annonascita" e "Cognome" che hai definito nella dichiarazione

    codice:
    public persone(int annonascita, String Cognome)
    ci sono i due valori 1950 e "Rossi". Tuttavia questi valori non sono ancora stati memorizzati nei due attributi che vuoi inizializzare, ma si trovano in due variabili locali! Lo devi fare esplicitamente, ed è quello che succede nelle righe successive:

    codice:
    annodinascita = annonascita;                  
    this.Cognome = Cognome;
    Non farti confondere dalla seconda istruzione: this.Cognome e Cognome sono due variabili DIVERSE: la prima è l'attributo dell'oggetto, la seconda la variabile locale. Nonostante il nome sia lo stesso, Java "sa" che sei in un costruttore e capisce quello che vuoi fare, risolvendosi da solo il problema dell'apparente ambiguità.
    Così com'è, funziona senza problemi. Tuttavia, se avessi dovuto scrivere io il codice avrei fatto

    codice:
    public persone(int default_annodinascita, String default_cognome)
    {
      this.annodinascita = default_annodinascita;
      this.cognome = default_cognome;
    }
    Preferisco una struttura del genere, ma solo per motivi di leggibilità (nota anche che ho chiamato "cognome" con la c minuscola, sempre per convenzione gli oggetti usano l'iniziale minuscola).

    In ultimo, gli altri due costruttori: semplicemente le due istruzioni

    codice:
    this(annonascita, "Non Conosco");
    
    this(0, Cognome);
    effettuano una chiamata "interna" al costruttore (int, String) già discusso prima: una sorta di catena diciamo. In questo modo, hai la possibilità, se vuoi, di creare un oggetto con le istruzioni

    codice:
    new persone(1950);
    
    new persone("Rossi");
    Nel primo caso gli attributi conterranno rispettivamente 1950 e "Con Conosco"; nel secondo, 0 e "Rossi".

    Spero di averti chiarito un po' di più le cose. Perdonami, ma a volte divento prolisso

  7. #7
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    1,085
    "desa" .. sei un grande !!
    così si spiegano le cose ..

    ho però un dubbio ..

    nel creare i 2 costruttori che mi permettono di assegnare col 'new' un solo attributo, utilizzo 'this', e immagino che Java distingua l'attributo 'annodinascita' dall'attributo 'Cognome' per il fatto che uno è 'int' e l'altro è 'string' ..
    ma se entrambi fossero stati 'int' .. avrei dovuto necessariamente scrivere 'this.annodinascita' e 'this.cognome' ?
    (chiaramente nell'esempio ho lasciato 'int' e 'String')

    codice:
      // Costruttori                                                 
    public Persone(int default_annodinascita)                                
    {this(default_annodinascita, "Non Conosco");  }                                                              
                                                                   
    public Persone(String default_cognome)                                 
    {this(0, default_cognome);        }
    codice:
      // Costruttori                                                 
    public Persone(int default_annodinascita)                                
    {this.annodinascita(default_annodinascita, "Non Conosco");  }                                                              
                                                                   
    public Persone(String default_cognome)                                 
    {this.cognome(0, default_cognome);        }

  8. #8
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Ok, ho capito cosa intendi: e la risposta è che non puoi farlo. E' esattamente come con l'overload dei metodi: non puoi averne due con lo stesso nome e con lo stesso TIPO e ORDINE dei parametri (importante!), altrimenti Java non sarebbe in grado di capire a quale dei due stai facendo riferimento.

    Ricordati poi che, se hai un metodo

    codice:
    public void tuoMetodo(int parametro1, String parametro2)
    {
    ... codice
    }
    i nomi delle variabili "parametro1" e "parametro2" sono LOCALI al metodo: diciamo che "nascono" con la parentesi graffa di apertura e "muoiono" con la parentesi graffa di chiusura. Non sono visibili nè raggiungibili dall'esterno del codice del metodo, servono solo al suo interno.
    Tieni anche presente che il this vuole indicare "questo oggetto", ossia l'oggetto "in cui ti trovi con il codice". Se hai un oggetto

    Oggetto ogg = new Oggetto();

    puoi invocare su di esso i metodi facendo

    ogg.metodo1();
    ogg.metodo2();

    oppure modificare gli attributi (se pubblici)

    ogg.attributo1 = valore1;
    ogg.attributo2 = valore2;

    Ma qui sei "all'esterno" dell'oggetto Oggetto. Se ti trovassi "all'interno", per fare riferimento ai suoi metodi e attributi con

    this.metodo1();
    this.attributo1 = valore1;

    oppure, essendo di default sottointeso, con

    metodo1();
    attributo1 = valore1;

    Quello che significa

    codice:
    this.annodinascita(default_annodinascita, "Non Conosco");
    è che vuoi eseguire un metodo dell'oggetto stesso che si chiama annodinascita (che, ovviamente, non esiste) e a cui passi come parametri due valori, un int ricevuto come parametro dal costruttore e una stringa costante "Non Conosco"

  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    1,085
    forse non mi son spiegato ...

    non posso avere due proprietà (con nome diverso) ma dello stesso tipo ?
    (nell'esempio 2 int)


    codice:
           class Persone                                                     
           {                                                                
               // Proprietà                                                   
             public int annodinascita;	                                     
             public int cognome;                            
                                                                                                          
               // Costruttori                                                 
             public Persone(int default_annodinascita)                                
             {this(default_annodinascita, 1);  }                                                              
                                                                            
             public Persone(int default_cognome)                                 
             {this(0, default_cognome);        }                                                         
           
             public Persone(int default_annodinascita, int default_cognome)     
             {                                                                     
               this.annodinascita = default_annodinascita;                         
               this.cognome = default_cognome;                                     
             }                                                                     
                                                                            
               // Metodo che calcola l'età del soggetto                       
             public int calcolaeta (int annoattuale)                        
             {                                                              
               return (annoattuale - annodinascita);                        
             }                                               
           }
    così:

    codice:
      // Costruttori                                                 
    public Persone(int default_annodinascita)                                
    {this(default_annodinascita, 1);  }                                                              
                                                                   
    public Persone(int default_cognome)                                 
    {this(0, default_cognome);        }
    mi dà i seguenti errori:
    - Persone(int) is already defined in Persone

    così:

    codice:
      // Costruttori                                                 
    public Persone(int default_annodinascita)                                
    {this.annodinascita(default_annodinascita, 1);  }                                                              
                                                                   
    public Persone(int default_cognome)                                 
    {this.cognome(0, default_cognome);        }
    mi dà i seguenti errori:
    - Persone(int) is already defined in Persone
    - cannot find symbol method annodinascita(int,int)
    - cannot find symbol method cognome(int,int)

  10. #10
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    E' esattamente così: non puoi avere due costruttori di una classe che ricevono lo stesso numero e tipo di parametri.

    Nel tuo caso hai creato due costruttori

    public Persone(int default_annodinascita)
    public Persone(int default_cognome)

    Se tu effettuassi una chiamata

    new Persone(10)

    come farebbe Java a sapere a quale dei due deve fare riferimento? I costruttori devono essere distinguibili, e per questo ognuno deve essere unico in termini di numero e/o tipo di parametri.
    (Cosa importante: non ti far confondere dal fatto che i nomi delle variabili parametro sono diversi, come ti ho detto si tratta di identificatori visibili solo dall'interno del costruttore, non dall'esterno).

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.