Newsgroup: it.comp.java
Titolo: [Teoria] Come risolvere elegantemente la non ereditarietà di un attributo private?

Ciao a tutti!
Nell'ambito dello studio di Java per l'esame di Lunguaggi, sono arrivato 
allo studio dei modificatori di metodi ed attributi, il loro overriding 
e i singoletti.
Uno degli esercizi presuppone l'esistenza di queste due semplici classi:
public class Conto {
     private double saldo;
     public Conto(double saldo_iniziale) {
         saldo = saldo_iniziale;
     }
     public double getSaldo () {
         return saldo;
     }
     public boolean deposita (double somma) {
         saldo = saldo + somma;
         return true;
     }
     public boolean preleva (double somma) {
         if (saldo >= somma) {
             saldo = saldo - somma;
             return true;}
         else return false;
         }
}
public class ContoCorrente extends Conto{
     private double scoperto;
     public ContoCorrente(double saldo) {
         super(saldo);
     }
     public ContoCorrente(double saldo, double scoperto) {
         this(saldo);
         this.scoperto = scoperto;
     }
     public boolean preleva (double somma) {
         if ((saldo+scoperto) >= somma) {
             saldo = saldo - somma;
             return true;
         }
         else return false;
     }
}
Il testo dell'esercizio dice: "E' possibile modificare la visibilitï¿œ 
protected di saldo nella classe Conto in modo che sia nuovamente private 
e ripristinare cosï¿œ l'incapsulazione perfetta?
La risposta ï¿œ sï¿œ. Ma questo ha conseguenze nel codice della classe 
ContoCorrente. Esibire le necessarie (ed eleganti) modifiche nella 
classe ContoCorrente che rendano nuovamente il programma funzionante.
Io ho pensato ad introdurre l'attributo saldo anche nella sottoclasse 
ContoCorrente e modificare i costruttori in modo che inizializzino 
questo attributo anzichï¿œ quello della superclasse con la chiamata a 
super(saldo). Perï¿œ tutto ciï¿œ non mi sembra molto "elegante".
Voi avete qualche suggerimento? Non ï¿œ una prova d'esame, vorrei 
semplicemente capire il ragionamento :)
Grazie!
-- 
Traveller, not tourist!
www.inter-rail.it

 semplicemente capire il ragionamento :)
In teoria, non devi usare l'attributo saldo nella classe ContoCorrente. 
Devi invece riscrivere il metodo preleva di ContoCorrente in modo che 
usi solamente i metodi pubblici della classe Conto.
In pratica, in questo specifico caso non lo puoi fare, dato che il 
metodo preleva della classe ContoCorrente puï¿œ violare il vincolo imposto 
invece dall'analogo metodo della classe Conto, cioï¿œ che il saldo non 
possa essere negativo.
In realtï¿œ, conoscendo il sorgente della classe Conto, si puï¿œ sfruttare 
la debolezza dell'implementazione della classe deposita, che non 
controlla che il parametro passatole sia positivo:
public boolean preleva (double somma) {
     if ((getSaldo()+scoperto) >= somma) {
         deposita(-somma);
         return true;
     }
     else return false;
}
Invece il modo giusto di scrivere la classe Conto, ï¿œ proprio quello di 
rendere protected l'attributo (o almeno dei setter/getter), rendendo 
quindi esplicito che quella classe ï¿œ stata pensata per essere estesa (e 
dando di conseguenza i mezzi necessari per farlo a chi ne ha bisogno).
Ciao
   Lucio
-- 
Lucio Benfante
JUG Padova           
http://www.parancoe.org
 ...have a look at it!
www.jugpadova.it
 
http://www.jugevents.org

 dando di conseguenza i mezzi necessari per farlo a chi ne ha bisogno).
Dillo al Prof. :-)


 inculcata.
ecco la sottoclasse corretta (credo)
public class ContoCorrente extends Conto{
     private double scoperto;
     private double rosso;
     public ContoCorrente(double saldo) {
         super(saldo);
     }
     public ContoCorrente(double saldo, double scoperto) {
         this(saldo);
         this.scoperto = scoperto;
     }
     public boolean deposita(double somma){
         if (rosso == 0) { //conto non in rosso
             super.deposita(somma);
             return true;
         }
         else if (rosso + somma < 0){ //conto ancora in rosso
             rosso = rosso + somma;
             return true;
         }
         else {
             super.deposita(somma-rosso);
             rosso=0;
             return true;
         }
     }
     public double getSaldo(){
         return super.getSaldo() + rosso;
     }
     public boolean preleva (double somma) {
         if ((super.getSaldo() + rosso + scoperto) >= somma) {
             if (super.getSaldo() - somma >= 0) { //conto non in rosso 
dopo prelievo
                 super.preleva(somma);
             }
             else { //conto in rosso dopo prelievo
                 rosso = rosso - (somma - super.getSaldo());
                 super.preleva(super.getSaldo());
             }
             return true;
         }
         else return false;
     }
}


 
volentieri...dammi il numero! :)


 
Se io fossi un professore osserverei questo newsgroup per poi suggerire
soluzioni particolari (e facili da riconoscere) e poi....
:-)