Problema con metodi set e get

di il
12 risposte

Problema con metodi set e get

Buonasera ragazzi...mi trovo in difficoltà con il seguente esercizio...potreste darmi una mano?
di seguito l'esercizio:

Scrivere una classe Pubblicazione i cui oggetti rappresentano pubblicazioni.Ogni oggetto Pubblicazione deve contenere le seguenti variabili d'istanza:
-Titolo(di tipo String)
-Autore(di tipo String)
-Numero di pagine(di tipo int)
-Prezzo di copertina(tipo di int)

la classe deve avere i seguenti metodi :

-Costruttore inizializza lo stato dell'oggetto
-metodi getTitolo,getAutore,getprezzo, get pagine che restituiscono i valore degli attributi ,
- metodi setTitolo etc ..... che modificano i valori degli attributi.
-metodo tostring che restituisce una stringa con i dati dell'oggetto su cui è invocato.

Purtroppo ho iniziato da poco a programmare e mi sono bloccato... potreste cortesemente darmi una mano?

vi ringrazio in anticipo!

12 Risposte

  • Re: Problema con metodi set e get

    Cos'è che ti blocca nello specifico?
    Sai cos'è un oggetto e come lo si definisce in java?
    Sai cos'è un metodo e come si fa in Java?

    Se sai queste cose vedi che piano piano ci riesci...Se c'è poi qualcosa che non sai fare è un altro conto...
  • Re: Problema con metodi set e get

    Posto il codice sorgente che ho scritto:


    public class Pubblicazione {
    public String Titolo;
    public String Autore;
    public int NumeroPagine;
    public int Prezzo;

    public String getTitolo() {
    return Titolo;
    }

    public String getAutore() {
    return Autore;
    }

    public int getPrezzo() {
    return Prezzo;
    }

    public int getNumeroPagine() {
    return NumeroPagine;
    }

    }

    diciamo che non riesco a sviluppare la classe Principale con il metodo main. il primo problema sarebbe il metodo set che non so come usarlo perchè non capisco a cosa serve... di seguito l'inizio del codice Principale:


    public class Principale {

    public static void main(String[] args) {
    Pubblicazione oggetto1 = new Pubblicazione();
    oggetto1.Titolo = "Il codice da vinci";
    oggetto1.Autore = "Dan Brown";
    oggetto1.NumeroPagine = 300;
    oggetto1.Prezzo = 12;

    }
    }
  • Re: Problema con metodi set e get

    sweeney1989 ha scritto:


    diciamo che non riesco a sviluppare la classe Principale con il metodo main. il primo problema sarebbe il metodo set che non so come usarlo perchè non capisco a cosa serve...
    Se metti una variabile di istanza come "public"
    public class Pubblicazione {
        public String titolo;
    
        // ......
    }
    Innanzitutto violi il principio di incapsulamento. L'accesso al campo titolo è diretto e sarà sparpagliato in qualunque altro numero di classi che ci accedono. Non potrai imporre logiche particolari (del tipo: il campo titolo non può essere null) proprio perché l'accesso è diretto e aperto a tutti.

    Per sfruttare il principio di incapsulamento, si mette il campo di norma "private" e si mettono dei metodi getter/setter pubblici (in generale detti "accessori", nel senso che permettono l'accesso indiretto al campo)
    public class Pubblicazione {
        private String titolo;
    
        public String getTitolo() {
            return titolo;
        }
    
        public void setTitolo(String titolo) {
            this.titolo = titolo;
        }
    }
    In questo modo l'accesso al campo non può più essere diretto. TU che scrivi la classe Pubblicazione hai il controllo di qualunque eventuale logica di validazione e/o gestione del campo.

    Tipo impedire di poter assegnare un null:
        public void setTitolo(String titolo) {
            if (titolo == null) {
                throw new IllegalArgumentException("Il titolo non può essere null");
            }
    
            this.titolo = titolo;
        }
  • Re: Problema con metodi set e get

    Mmm non ho caputo molto... innanzitutto non mi è stato spiegato il principio dell'incapsulamento...mi è stato dato solo questo esercizio dicendo di risolverlo utilizzando metodi mai affrontati... come risolvereste l'esercizio?
  • Re: Problema con metodi set e get

    sweeney1989 ha scritto:


    innanzitutto non mi è stato spiegato il principio dell'incapsulamento...
    male .... ma magari (spero!) lo faranno in seguito.

    sweeney1989 ha scritto:


    come risolvereste l'esercizio?
    Una classe Pubblicazione con:
    - variabili di istanza marcate private (e nota, per convenzione, con nomi che iniziano con la minuscola es. titolo non Titolo)
    - metodi "getter"/"setter" marcati public: getTitolo, setTitolo, getAutore, ecc...
    - costruttore marcato public che magari (presumo sia quello che vogliono) riceve i 4 dati e li assegna alle variabili di istanza
    - metodo public String toString() che restituisce una stringa con una descrizione (formato a tua scelta o secondo quanto richiesto) della pubblicazione.
  • Re: Problema con metodi set e get

    andbin ha scritto:


    Una classe Pubblicazione con:
    - variabili di istanza marcate private (e nota, per convenzione, con nomi che iniziano con la minuscola es. titolo non Titolo)
    - metodi "getter"/"setter" marcati public: getTitolo, setTitolo, getAutore, ecc...
    - costruttore marcato public che magari (presumo sia quello che vogliono) riceve i 4 dati e li assegna alle variabili di istanza
    - metodo public String toString() che restituisce una stringa con una descrizione (formato a tua scelta o secondo quanto richiesto) della pubblicazione.
    Sono appena arrivato anch'io a questo punto della programmazione (dopo la ricorsione) e vorrei in particolare un chiarimento in merito ai metodi set.
    Partendo ovviamente dal presupposto che tutto dipende dall'esercizio in esame, in linea di massima questi metodi conviene crearli direttamente con la possibilità di inserimento da tastiera (usando la classe Scanner) o conviene creare un metodo a parte (per esempio con public void leggiInput()) che faccia questo, dando al metodo set solo le modifiche delle variabili d'istanza? Lo stesso dubbio ce l'ho per la gestione delle eccezioni (che per ora affronto solo con if e while, per esempio casi di numero negativo o stringa null): meglio dentro i metodi set o in leggiInput()?
  • Re: Problema con metodi set e get

    Raziel84 ha scritto:


    in linea di massima questi metodi conviene crearli direttamente con la possibilità di inserimento da tastiera (usando la classe Scanner) o conviene creare un metodo a parte (per esempio con public void leggiInput()) che faccia questo, dando al metodo set solo le modifiche delle variabili d'istanza?
    I metodi "accessori" getter e setter non c'entrano nulla con l'input dell'utente. Ma riguardano invece il principio di incapsulamento.
    Se una classe Persona ha un campo (variabile di istanza) "nome", invece di renderlo public (accessibile da chiunque all'esterno della classe), lo si tiene private (solo accessibile dalla classe in cui è) e poi si mettono i metodi public "accessori" getter e/o setter. Ci sono motivazioni ben importanti per NON far accedere direttamente al campo!

    Raziel84 ha scritto:


    Lo stesso dubbio ce l'ho per la gestione delle eccezioni (che per ora affronto solo con if e while, per esempio casi di numero negativo o stringa null): meglio dentro i metodi set o in leggiInput()?
    La questione è posta un po' male. Nel senso che un metodo "setter" può anche lanciare una eccezione (es. tipicamente la java.lang.IllegalArgumentException) se il valore passato non è valido. Ma questo riguarda solo gli invarianti che ci sono nella classe (es. "il lato di un cubo non può essere mai negativo"). Non riguarda l'input dell'utente!

    A livello di input dell'utente invece anche qui si potrebbe lanciare una eccezione ma dipende da come si vuole gestire l'input. A parte eccezioni "tecniche" (es. IOException), se si legge es. con nextInt() di Scanner e l'input è "malformato", sbuca fuori un InputMismatchException ma lo si può catturare (buttando via il token malformato), scrivere all'utente "hai sbagliato, inserisci di nuovo" e ripetere l'input. Tutto questo dentro un ipotetico leggiIntero()

    Insomma le due cose setter e input sono a livelli differenti.
  • Re: Problema con metodi set e get

    andbin ha scritto:


    I metodi "accessori" getter e setter non c'entrano nulla con l'input dell'utente. Ma riguardano invece il principio di incapsulamento.
    Se una classe Persona ha un campo (variabile di istanza) "nome", invece di renderlo public (accessibile da chiunque all'esterno della classe), lo si tiene private (solo accessibile dalla classe in cui è) e poi si mettono i metodi public "accessori" getter e/o setter. Ci sono motivazioni ben importanti per NON far accedere direttamente al campo!
    Sull'utilizzo del private non ci sono dubbi, la mia richiesta era per esempio se conviene creare qualcosa del genere...
    
    public void setNome(String nome)
    {
    	this.nome = nome;
    }
    
    public void leggiInput()
    {
    	System.out.println("Inserisci nome:");
    	nome = input.next();	
    }
    
    oppure...
    
    public void setNome()
    {
    	Scanner input = new Scanner(System.in);
    	System.out.println("Inserisci nome:");
    	nome = input.next();
    }
    
    Entrambi fanno lo stesso lavoro, ma quale dei due è correttamente valido ai fini dell'incapsulamento? Chiedo questo perchè ho visto in anticipo che ci sono esercizi sul mio libro dove addirittura mi viene chiesto che l'inserimento da tastiera di un valore lo vuole dentro un metodo get. Insomma, devo fare chiarezza su questo passaggio
    Le eccezioni da te menzionate invece non le ho ancora affrontate, ma solo semplici controlli da mettere dentro i metodi set. Tipo:
    
    if (n < 0)
    {
    	System.out.println("Valore non consentito");
    	System.exit(0);
    }
    
    // O in altenativa
    
    while(n < 0)
    {
    	System.out.println("Valore non consentito. Si prega di inserire un valore maggiore o uguale a zero.");
    	n = input.nextInt();	
    }
    
  • Re: Problema con metodi set e get

    Raziel84 ha scritto:


    la mia richiesta era per esempio se conviene creare qualcosa del genere...
    
    public void setNome(String nome)
    {
    	this.nome = nome;
    }
    
    public void leggiInput()
    {
    	System.out.println("Inserisci nome:");
    	nome = input.next();	
    }
    
    oppure...
    
    public void setNome()
    {
    	Scanner input = new Scanner(System.in);
    	System.out.println("Inserisci nome:");
    	nome = input.next();
    }
    
    Entrambi fanno lo stesso lavoro, ma quale dei due è correttamente valido ai fini dell'incapsulamento?
    Nessuno dei due è davvero ottimo. E NON è una questione di incapsulamento ... ma di "design".

    Un input con Scanner in un setNome assolutamente NO. Tra l'altro quando Scanner è agganciato a System.in, di questo oggetto Scanner ce ne dovrebbe essere uno solo in tutta la applicazione. Mentre invece così è ripetuto e ricreato ogni volta.

    Ma il punto fondamentale è che se il nome è settabile SOLO con quel setNome, quella tua classe è legata esclusivamente all'input dall'utente. Se si volesse settare il nome preso da un file, da un componente grafico o altro, non puoi (ri)usare questa tua classe.

    Il primo codice, ovvero il setNome come setter "pulito" e poi il leggiInput() separato, è solo un pelino pelino meglio. Ma la tua classe è comunque mescolata con una forma specifica di input dei dati.

    Queste sono problematiche di "design" delle classi. Se fai una classe es. Persona, questa dovrebbe essere focalizzata su un solo aspetto: rappresentare una persona. Non vuol dire che deve avere pochi campi o pochi metodi. Ne può avere quanti ne vuoi e quanti ne servono. Vuol dire che la classe Persona non dovrebbe fare cose radicalmente differenti dalla sola rappresentazione di una entità persona.

    Quindi: niente input dall'utente, niente output su componenti grafici o console, niente accesso a DB, niente accesso a file, ecc...

    In sostanza: classe Persona, con i vari campi (possibilmente private), metodi setter e/o getter public, altro eventuale (toString(), equals(), ecc..) più altro che può essere utile per la rappresentazione della persona.

    E quindi tu dirai: e l'input dove va? Da un'altra parte certamente, in un'altra classe più focalizzata all'input di una persona.

    Raziel84 ha scritto:


    Chiedo questo perchè ho visto in anticipo che ci sono esercizi sul mio libro dove addirittura mi viene chiesto che l'inserimento da tastiera di un valore lo vuole dentro un metodo get.
    Vabbè .. discutibile (da verificare, comunque). Ma si tratta di esercizi ... non è la fine del mondo ...

    Raziel84 ha scritto:


    Le eccezioni da te menzionate invece non le ho ancora affrontate, ma solo semplici controlli da mettere dentro i metodi set. Tipo:
    
    if (n < 0)
    {
    	System.out.println("Valore non consentito");
    	System.exit(0);
    }
    Un System.exit(0) solo per questo è un po' troppo "radicale".

    Raziel84 ha scritto:


    while(n < 0)
    {
    	System.out.println("Valore non consentito. Si prega di inserire un valore maggiore o uguale a zero.");
    	n = input.nextInt();	
    }
    
    Dipende da dove lo fai ...
  • Re: Problema con metodi set e get

    Diciamo quindi che per ora la versione corretta dei metodi set e get è quella "striminzita", cioè:
    
    public void setNome(String nome)
    {
    	// Eventuali controlli sulla correttezza della stringa tramite if o while e poi...
    	
    	this.nome = nome;
    }
    
    public void getNome()
    {
    	return nome;
    }
    
    // Solo per ora, creare a parte e nella stessa classe il metodo leggiInput() per leggere i dati da tastiera, più un eventuale scriviOutput().
    
    Successivamente sarebbe opportuno (magari lo noterò nei capitoli a seguire) creare proprio una classe a parte dedicata solo all'inserimento da tastiera, così da rendere tutto molto più semplice e lineare, nonché funzionale!
  • Re: Problema con metodi set e get

    Raziel84 ha scritto:


    
    public void setNome(String nome)
    {
    	// Eventuali controlli sulla correttezza della stringa tramite if o while e poi...
    	
    	this.nome = nome;
    }
    "if" sì, "while" .. uhm, direi di no. Questo è un setter, se il parametro non è valido (es. se si vuole impedire null o stringa vuota) ci sono principalmente due opzioni sensate: la prima, non fare l'assegnamento al campo (ovvero non fa nulla) che non è il massimo; la seconda (molto migliore), lanciare fuori una eccezione (es. la IllegalArgumentException).

    Raziel84 ha scritto:


    Successivamente sarebbe opportuno (magari lo noterò nei capitoli a seguire) creare proprio una classe a parte dedicata solo all'inserimento da tastiera, così da rendere tutto molto più semplice e lineare, nonché funzionale!
    Sì, devi ancora "maturare" conoscenza su questi aspetti più di "design" delle classi.
  • Re: Problema con metodi set e get

    Grazie mille. Sempre molto esaustivo!
Devi accedere o registrarti per scrivere nel forum
12 risposte