package esprreali;

public class Somma extends EsprReale {
  private EsprReale e1;
  private EsprReale e2;

	// il costruttore deve necessariamente avere due
	// argomenti, dato che viene specificato che la somma ha
	// sempre due addendi (mai zero oppure uno). Il
	// testo del problema specifica che le due
	// componenti di una somma sono due espressioni,
	// ossia non possono valere null; poter controllare
	// che non vengano inseriti valori sbagliati nelle
	// componenti di un oggetto e' uno dei vantaggi
	// dell'incapsulamento
  public Somma(EsprReale a, EsprReale b) {
    if((a==null)||(b==null))
      throw new RuntimeException("Le espressioni non possono valere null");
    e1=a;
    e2=b;
  }

	// deve essere possibile accedere alle due componenti di
	// una somma
  public EsprReale prima() {
    return e1;
  }
  public EsprReale seconda() {
    return e2;
  }

  // il metodo toString deve restituire esattamente quello
  // che viene richiesto: le due espressioni con + in mezzo
  public String toString() {
    return e1.toString()+"+"+e2.toString();
  }

	// il confronto va fatto nel modo standard: dato che le
	// due componenti di questa classe sono oggetti, vanno
	// confrontati con equals; qui sotto viene riportato il
	// metodo equals generale, ma in questo caso le due
	// componenti non possono valere null per come e'
	// fatto il costruttore;
  public boolean equals(Object o) {
    if(!this.stessaClasse(o))
      return false;

    Somma s=(Somma) o;

    if(this.e1==null) {
      if(s.e1!=null)
        return false;
    }
    else if(!this.e1.equals(s.e1))
      return false;

    if(this.e2==null) {
      if(s.e2!=null)
        return false;
    }
    else if(!this.e2.equals(s.e2))
      return false;

    return true;
  }

	// questo e' il modo corretto di implementare hashCode;
	// fare la somma non pesata degli hashCode delle
	// componenti e' un errore (piccolo, ma e' un errore).
	// Fare attenzione: se invece di ris=ris*7+ si fa
	// ris=ris+7*..., allora si sta facendo la somma (anche se
	// poi viene moltiplicata per 7), e non la somma pesata
  public int hashCode() {
    int ris=5;

    ris=ris*7+e1.hashCode();
    ris=ris*7+e2.hashCode();

    return ris;
  }

	// per la clonazione di Somma ci atteniamo al metodo
	// generale di clonare usando il metodo della
	// sovraclasse e poi cambiare le componenti; in
	// questo caso, puo' sembrare non necessario, dato
	// che poi tutte e due le componenti vanno cambiate;
	// invece va fatto, perche' altrimenti un
	// cambiamento nella sovraclasse (per esempio,
	// l'aggiunta di una componente) renderebbe non
	// funzionante questo metodo; in generale, le classi
	// dovrebbere essere il piu' possibile indipendenti
	// fra loro
  public Object clone() {
    Somma s=(Somma) super.clone();
    s.e1=(EsprReale) e1.clone();
    s.e2=(EsprReale) e2.clone();
    return s;
  }
}

