package esprreali;

// Questa classe rappresenta tutti gli oggetti di tipo
// "espressione di reali". Dal momento che non e' possibile
// realizzare toString, equals e hashCode a questo livello,
// non vengono ridefiniti. La classe contiene quindi solo
// metodi ausiliari (concreti) e il metodo clone (vedi
// sotto).

// NOTA IMPORTANTE: nella sovraclassi (come questa) non deve
// apparire in nessun modo il nome delle sottoclassi; per
// esempio, scrivere il metodo toString qui, facendo tutti i
// vari casi (if(o instanceof Costante)...) e' un errore
// grave; se si volesse per esempio aggiungere una nuova
// sottoclasse (per esempio, Differenza), bisognerebbe ogni
// volta andare a modificare la sovraclasse.

// L'interfaccia Cloneable viene implementata nella
// sovraclasse: in questo modo, tutte le sottoclassi
// implementano automaticamente questa interfaccia. Il
// metodo clone va necessariamente ridefinito in questa
// classe perche', per definizione, si deve poter fare
// e.clone() quando "e" e' una variabile di tipo EsprReale.
// L'eccezione CloneNotSupportedException va catturata nel
// clone di questa classe per lo stesso motivo.

public abstract class EsprReale implements Cloneable {
	// metodo ausiliario di confronto classi, da usare
	// nelle sottoclassi all'interno del loro metodo
	// equals; la protezione e' a livello di package,
	// dal momento che si tratta di un metodo che deve
	// essere usato solo all'interno delle altre classi
	// del package; e' un errore chiamare "equals" un
	// metodo fatto in questo modo, perche' equivale a
	// dire che, di default, due oggetti EsprReale sono
	// uguali se sono della stessa classe
  boolean stessaClasse(Object o) {
    if(o==null)
      return false;

    return this.getClass()==o.getClass();
  }

	// clonazione superficiale; in questo classe, la
	// clonazione non si puo' definire profonda, perche'
	// altrimenti bisognerebbe fare riferimento alle
	// sottoclassi; d'altra parte, il metodo clone deve
	// sempre poter essere invocato su un oggetto che
	// sta in una variabile EsprReale, e quindi il
	// metodo deve necessariamente ridefinita public a
	// questo livello, e l'eccezione va catturata
	// necessariamente a questo livello
  public Object clone() {
    try {
      return super.clone();
    }
    catch(CloneNotSupportedException e) {
      return null;
    }
  }
}

