2013-03-26 12 views
5

Sono bloccato con un problema qui. Voglio cambiare il setter da un attributo della superclasse (classe genitore) nella mia sottoclasse (figlio), tuttavia quando sovrascrivo questo metodo nella mia sottoclasse non posso accedere ai miei attributi privati ​​dalla supperclass. E il punto è che devono rimanere privati.Ignora setter in sottoclasse

Superclass (problema: setMinimumVoorraad (int voorraad);)

pacchetto domein;

public abstract class Artikel implements Weegbaar 
{ 
    private String omschrijving; 
    private double prijs; 
    private int aantalInStock; 
    private int minimumVoorraad; 

    public Artikel(String omschrijving, double prijs, int aantalInStock, int minimumVoorraad) 
    { 
     this.setOmschrijving(omschrijving); 
     this.setPrijs(prijs); 
     this.setAantalInStock(aantalInStock); 
     this.setMinimumVoorraad(minimumVoorraad); 
    } 

    @Override 
    public String toString() 
    { 
     String output = String.format(" \n omschrijving: %s \n prijs: %f \n In stock %d (minimumvoorraad = %d) \n", this.omschrijving, this.prijs, this.aantalInStock, this.minimumVoorraad); 
     return output; 
    } 
//----Getters---- 
    public String getOmschrijving() { 
     return omschrijving; 
    } 

    public double getPrijs() { 
     return prijs; 
    } 

    public int getAantalInStock() { 
     return aantalInStock; 
    } 

    public int getMinimumVoorraad() { 
     return minimumVoorraad; 
    } 

//----Setters---- 
    public void setOmschrijving(String omschrijving) { 
     this.omschrijving = omschrijving; 
    } 

    public void setPrijs(double prijs) { 
     this.prijs = prijs; 
    } 

    public void setAantalInStock(int aantalInStock) { 
     this.aantalInStock = aantalInStock; 
    } 

    public void setMinimumVoorraad(int minimumVoorraad) 
    { 
     if(minimumVoorraad < 2) 
      this.minimumVoorraad = 3; 
     else 
      this.minimumVoorraad = minimumVoorraad; 
    } 


} 

sottoclasse

package domein; 


public class Food extends Artikel 
{ 

    private String houdbaarheidsDatum; 
    private double nettoGewicht; 

    public Food(String omschrijving, double prijs, int aantalInStock, int minimumVoorraad, String houdbaarheidsDatum, double nettoGewicht) 
    { 
     super(omschrijving, prijs, aantalInStock, minimumVoorraad); 
     this.setHoudbaarheidsDatum(houdbaarheidsDatum); 
     this.setNettoGewicht(nettoGewicht); 
    } 

    @Override 
    public boolean isWeegbaar() 
    { 
     return true; 
    } 


//----Getters---- 
    public String getHoudbaarheidsDatum() { 
     return houdbaarheidsDatum; 
    } 

    public double getNettoGewicht() { 
     return nettoGewicht; 
    } 

//----Setters---- 
    public void setHoudbaarheidsDatum(String houdbaarheidsDatum) { 
     this.houdbaarheidsDatum = houdbaarheidsDatum; 
    } 

    public void setNettoGewicht(double nettoGewicht) { 
     this.nettoGewicht = nettoGewicht; 
    } 

    @Override 
    public void setMinimumVoorraad(int minimumVoorraad) 
    { 
     if(minimumVoorraad < 5) 
      this.minimumVoorraad = 6; 
     else 
      this.minimumVoorraad = minimumVoorraad; 
    } 


} 

Qualcuno che mi può aiutare? Grazie in anticipo.

+1

Ovviamente, dobbiamo vedere il codice. –

risposta

2

La risposta di cui sopra dal NPE è assolutamente il modo migliore per andare sulla risoluzione del problema. È elegante e onora i contratti di ereditarietà di base tra la superclasse e la sottoclasse. Anche nel tuo post originale, la sottoclasse è in realtà più restrittiva della superclasse, in modo da fare qualcosa di simile:

@Override 
public void setMinimumVoorraad(int minimumVoorraad) 
{ 
    if(minimumVoorraad <= 5) 
     super.setMinimumVoorraad(6); 
    else 
     super.setMinimumVoorraad(minimumVoorraad); 
} 

esattamente come NPE suggerito probabilmente funzionerà. (Si noti come ho modificato il test if. Non sono sicuro se si tratta di un errore di battitura, ma nella realizzazione originale 5 sarebbe un minimo valido, ma in ingresso come 4 sarebbe impostarla 6.)

Altri modelli (possibilmente accettabile) sarebbe essere a:

  1. rendere i membri della tua classe Parent protected, che darebbe visibilità. (Accertati di aver menzionato una limitazione private, questo modello è solo menzionato per fornire una risposta globale più completa.)
  2. Delegare la logica di convalida a un altro metodo (che non è privato). In questo modo il bambino può sovrascrivere il metodo di convalida.

E ora al (probabilmente inaccettabile) modello di utilizzo di Java riflessione:

@Override 
public void setMinimumVoorraad(int minimumVoorraad) { 

    try { 
     Field field = this.getClass().getSuperclass().getDeclaredField("minimumVoorraad"); 
     field.setAccessible(true); 

     if(minimumVoorraad <= 5) 
      field.set(this, 6); 
     else 
      field.set(this, minimumVoorraad); 

     field.setAccessible(false); 
    } 
    catch(NoSuchFieldException | IllegalAccessException e) { 
     // do something 
    } 
} 

vale la pena notare che se mai e poi mai fare questo in tutta la tua vita che sarà probabilmente il migliore per esso . Non solo completamente interrompe tutti i contratti, ma si basa su stringhe codificate per eseguire ricerche sul nome di campo, che di per sé è piuttosto doloroso. Ma esiste. E nessuna buona risposta (già fornita da NPE) sarebbe completa senza un esempio di come non fare qualcosa ...

9

Una possibilità è quella di implementare il setter della sottoclasse in termini di setter della superclasse (che, presumibilmente, si ha accesso a).

Per esempio, supponendo che il setter è setFoo, quindi la versione del sottoclasse potrebbe essere:

public void setFoo(Foo f) { 

    // Do subclass stuff pre-setting, if any 

    super.setFoo(f); 

    // Do subclass stuff post-setting, if any 
} 
+0

Più breve e più chiaro del mio, +1 –

+0

@ T.J.Crowder: Grazie per la modifica. – NPE

+0

Grazie, ma mi piace sbarazzarmi delle condizioni già definite nella mia superclasse. – Energyfellow