Un esercizio sugli accessi

Esercizio


Testo

Definire una classe con incapsulamento che rappresenta i dati di uno studente:

Definire un metodo statico che calcola come si modifica una media di interi quando viene aggiunto un nuovo intero. Sono dati: la media attuale, il numero di interi, il nuovo intero.

La classe deve essere incapsulata.

Definire i costruttori, seguendo i vincoli riportati qui sotto.

Si implementi la classe in modo tale che non sia possibile:

Definire il metodo statico che ritorna un oggetto studente i cui dati vengono letti da tastiera.


Come affrontare un problema complesso

Si procede un passo per volta.

Intanto: la classe ha componenti e metodi.


Componenti

Sono dati nel testo:

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  // metodi
}

Incapsulamento: dopo.


Il metodo statico

Intestazione del metodo:

static double nuovaMedia(double media, int numero, int nuovo) {
  ...
}

Il metodo

Facendo media*numero ottengo la somma.

Se faccio somma+nuovo/(numero+1) ottengo la nuova media.

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  static double nuovaMedia(double media, int numero, int nuovo) {
    double somma=media*numero;
    return (somma+nuovo)/(numero+1);
  }

  // altri metodi
}

Attenzione: si tratta di una valutazione approssimata!


Incapsulamento

L'incapsulamento si fa al contrario:

  1. dichiaro tutto privato
  2. implemento solo i metodi che realizzano un accesso consentito

Prima di implementare, occorre vedere cosa è permesso fare.


I metodi get

Se non c'è scritto niente, tutte le componenti sono accessibili in lettura.

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  // metodo nuovaMedia 

  String getNome() {
    return this.nome;
  }

  String getData() {
    return this.data;
  }

  int getEsami() {
    return this.esami;
  }

  double getMedia() {
    return this.media;
  }
}

Costruttori

I costruttori sono metodi che scrivono un valore nelle componenti quando gli oggetti vengono creati

Quali costruttori creare?

Di solito, ci sono tutte le possibilità:

Studente()
Studente(String nome)
Studente(String data)
Studente(String nome, String data)
Studente(int esami)
...

Nel nostro caso:

Quindi, sono ammessi:

Quindi, restano solo:

  Studente(String nome, String data)
  Studente(String nome, String data, int esami, int media)

Implementazione dei costruttori

Solito modo:

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  Studente(String nome, String data) {
    this.nome=nome;
    this.data=data;
  }

  Studente(String nome, String data, int esami, double media) {
    this.nome=nome;
    this.data=data;
    this.esami=esami;
    this.media=media;
  }

  // altri metodi
}

Di solito, i costruttori si mettono prima degli altri metodi


Versione con controllo

Controllo che nome e data non siano null:

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  Studente(String nome, String data) {
    if( (this.nome==null)||(this.data==null) ) {
      // errore
    }

    this.nome=nome;
    this.data=data;
  }

  Studente(String nome, String data, int esami, int media) {
    if( (this.nome==null)||(this.data==null) ) {
      // errore
    }

    this.nome=nome;
    this.data=data;
    this.esami=esami;
    this.media=media;
  }

  // altri metodi
}

Metodi di scrittura

Vincoli:

Quindi:


Implementazione del metodo set

Come al solito:

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  // altri metodi

  void setEsamiMedia(int esami, double media) {
    this.esami=esami;
    this.media=media;
  }
}

Cambiare nome ed esame

  Studente s=new Studente("Pippo", "12/2/1938");

  s=new Studente("Topolino", "1/1/1930");

Sembra che sia stato cambiato l'oggetto.

In realtà nessuno oggetto è stato modificato.

È stato creato un nuovo oggetto, il cui indirizzo è stato messo nella variabile.

Il vincolo è soddisfatto.


L'altro metodo statico

Leggo i dati da tastiera e restituisco un oggetto con dentro questi dati.

L'oggetto non va passato come parametro

Il metodo crea l'oggetto


Implementazione del metodo

Come al solito: leggo un dato per volta, e lo converto se serve.

import javax.swing.*;

class Studente {
  String nome;
  String data;
  int esami;
  double media;

  // altri metodi

  static Studente readKb() {
    String nome=JOptionPane.showInputDialog("Scrivi il nome");
    String data=JOptionPane.showInputDialog("Scrivi la data di nascita");

    String s;
    s=JOptionPane.showInputDialog("Scrivi il numero di esami");
    int esami=Integer.parseInt(s);

    s=JOptionPane.showInputDialog("Scrivi la media");
    double media=Double.parseDouble(s);

    return (new Studente(nome, data, esami, media));
  }
}

Programma di prova

Con BlueJ si possono direttamente creare gli oggetti, oppure invocare i metodi.

Nota: quando un metodo ritorna un oggetto, se lo si vuole salvare, evidenziare la riga result= <object referece>, e fare get

Si può comunque scrivere un programma di prova.

public class ProvaStudente
{
  public static void main(String args[]) {
    Studente s;
    s=new Studente("Pippo", "12/3/1939");
    
    Studente t;
    t=new Studente("Topolino", "12/2/1943", 12, 19.2);
    
    System.out.println(s.getNome());
    
    s=Studente.readKb();
    
    System.out.println(s.getNome());
  }
}

Scrivere altre invocazioni di metodo.