Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    Cross-calling Costruttori

    Salve,
    volevo sapere come faccio una cross-calling tra costruttori nel seguente caso

    codice:
    public class User {
    	private String username,password;
    	
    	public User() { //costruttore con 0 argomenti
    		String nome,pass;
    		// leggo nome e pass
    		this(nome,pass); //in questo punto vorrei chiamare il costruttore con 2 argomenti per completare l'istanza
    	}
    	
    	public User(String Nome,String Pass) { //costruttore con 2 argomenti
    		System.out.println("Creato l'utente "+Nome);
    		username= Nome;
    		password= Pass;
    	}
    purtroppo il compilatore mi dice che la chiamata a costruttori, fatta nel metodo User(), dev'essere la prima istruzione del metodo. Tuttavia se non leggo prima nome e pass non ha senso richiamare il costruttore con 2 argomenti.

    Come posso fare?

    LA MIA SOLUZIONE: avevo pensato ai parametri di default nel costruttore a 2 argomenti, e in esso, prima di fare le assegnazioni, controllo prima il valore contenuto nei parametri. Se questi sono i valori di default allora provvedo a fare la lettura e poi l'assegnazione. Posso fare solo in questo modo?

    Grazie
    Forza e onore

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Ci sono parecchie regolette relative ai costruttori. Tra queste vi è quella che un costruttore deve sempre e comunque iniziare esclusivamente o con un super() o con un this().

    Anche quando ad esempio fai:
    codice:
    class XYZ
    {
        public XYZ ()
        {
            System.out.println ("ciao");
        }
    }
    La chiamata a super() c'è lo stesso ..... viene infatti inserita dal compilatore!
    In ogni caso, anche se usi this(), prima o poi dovrà esser fatta una super().

    Torniamo al tuo problema:
    codice:
    public User() { //costruttore con 0 argomenti
    	String nome,pass;
    	// leggo nome e pass
    	this(nome,pass); //in questo punto vorrei chiamare il costruttore con 2 argomenti per completare l'istanza
    }
    Tu leggi nome e pass da dove??? Presumo dallo standard input, inserito dall'utente .....
    Premetto che un "design" del genere non è certamente molto bello, comunque c'è un'altra regoletta relativa ai costruttori: fino a quando il super-costruttore non è stato eseguito, il "this" non è utilizzabile nella classe. Ciò significa che fino a quando il super() non è stato eseguito, non puoi usare metodi/variabili di istanza ...... però puoi usare metodi/variabili statici!!

    Ecco un esempio:
    codice:
    import java.util.*;
    
    public class Prova
    {
        private String nome;
    
        public Prova ()
        {
            this (inputNome ());
        }
    
        public Prova (String nome)
        {
            this.nome = nome;
        }
    
        private static String inputNome ()
        {
            Scanner sc = new Scanner (System.in);
            System.out.print ("Nome: ");
            return sc.nextLine ();
        }
    
        public static void main (String[] args)
        {
            Prova p = new Prova ();
        }
    }
    Nota che inputNome() è static, perciò lo puoi chiamare mentre passi il parametro a this().
    Se una tale soluzione sia un design valido o meno ..... non lo so, non sono un "guru" di Java. Però dal mio punto di vista, fa schifo ....
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Direi che la tua soluzione dei valori di default è più che valida. Al massimo per evitare "valori fissi" di default potresti usare una stringa vuota.
    Al mio segnale... scatenate l'inferno!

  4. #4

    Consigliami

    Originariamente inviato da andbin
    Se una tale soluzione sia un design valido o meno ..... non lo so, non sono un "guru" di Java. Però dal mio punto di vista, fa schifo ....
    Beh nemmeno io sono un "guru", dato che esprimi giudizio, ti inviterei a consigliarmi una tua soluzione al problema, ossia predisporre un giusto costruttore se l'oggetto è istanziato con o senza passargli i parametri di inizializzazione.
    Forza e onore

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Anche a me non piace molto quella soluzione.
    Infatti, secondo la logica della programmazione ad oggetti, un oggetto viene costruito quando si hanno in mano tutti gli elementi per farlo.

    Se devi leggere da qualche parte i dati per la costruzione dell'oggetto, la soluzione più ovvia, più banale e più sensata è quella di leggerli prima di costruirlo.

    Considerando che qualsiasi applicazione parte da un contesto statico (il main), non vedo perchè si debba ricorrere ad una soluzione del genere, quando questa è più che sufficiente:
    codice:
    public class MiaClasse {
       public MiaClasse(String s1, String s2) {
          ...
       }
    
       ...
    
       public static void main(String [] args) {
          // Leggo i parametri da tastiera
          BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
          String s1 = br.readLine();
          String s2 = br.readLine();
    
          // Ora costruisco l'oggetto:
          MiaClasse mc = new MiaClasse(s1, s2);
       }
    }
    Se c'è l'esigenza di avere un costruttore di default, questo dovrà semplicemente passare due valori "standard" (ad esempio, due stringhe vuote) e la classe dovrà mettere a disposizione un metodo per la valorizzazione post-creazione. (E' questo il caso di oggetti soggetti a serializzazione).

    Casi più particolareggiati vengono risolti utilizzando campi di tipo transient.


    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

  6. #6

    Grazie

    Un grazie a tutti quelli che mi hanno aiutato, la soluzione che ho adottato è la seguente
    codice:
    public class User {
    
        private String username,password;
    
    
    
        public User() { //costruttore con 0 argomenti
    
            String nome,pass;
    
            // leggo nome e pass
    
            createUser(nome,pass);
    
        }
    
    
    
        public User(String Nome, String Pass) {
    
            createUser(Nome, Pass);
    
        }
    
    
    
        private createUser(String Nome,String Pass) {
    
            System.out.println("Creato l'utente "+Nome);
    
            username= Nome;
    
            password= Pass;
    
        }
    
    }
    Saluti.
    Forza e onore

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.