// gli oggetti Variabile devono essere clonabili

class Variabile implements Cloneable {

// nome della variabile; privato per via dell'incapsulamento

  private String nome;

// non esisono variabili senza nome

  public Variabile(String n) {
    if(n==null)
      throw new RuntimeException("Tentativo creazione variabile con nome null");

    nome=n;
  }

  public String getNome() {
    return nome;
  }

// si e' scelto di non realizzare un metodo setNome; non ha
// senso cambiare il nome di una variabile (si possono
// comunque creare variabile nuove con nuovi nomi)

  public String toString() {
    return nome;
  }

  public boolean equals(Object o) {
    if(o==null)
      return false;

    if(this.getClass()!=o.getClass())
      return false;

    Variabile v=(Variabile) o;

// qui this.nome non puo' valere null perche' il costruttore
// lo impedisce e non sono ammesse modifiche dirette alla
// componente; in caso contrario, andava verificato se
// this.nome era null prima di invocare il metodo equals

    return v.nome.equals(o);
  }

// dato che equals e' stato ridefinito, va ridefinito anche
// hashCode

  public int hashCode() {
    return nome.hashCode();
  }

// metodo di clonazione: dato che le stringhe non sono
// clonabili, basta la clonazione superficiale

  public Object clone() {
    try {
      return super.clone();
    }
    catch(CloneNotSupportedException e) {
      return null;
    }
  }
 
}
