Newsgroup: it.comp.java
Titolo: Re: Logica sull'implementazione delle interfacce

 Dov'e` l'errore che non mi fa ottenere il comportamento da me voluto?
 
Perché il tipo della variabile è Interfaccia, indipendentemente da cosa hai 
instanziato. E la classe Interfaccia non ha il metodo setAnotherName.
Per chiamare setAnotherName devi fare il cast.
 
In java il tipo di una variabile non è associato all'oggetto istanziato: 
esso non "sa" (reflection a parte) di che tipo è. Il tipo glielo dici tu.
 
    ((Implementante)implementante).setAnotherName("second name");
 
dovrebbe fare quello che vuoi.
 

     ((Implementante)implementante).setAnotherName("second name");
 
Che, messa cosi`, e` talmente orribile sia da vedere che da usare che e` 
meglio usare direttamente la classe derivata :D
In sostanza, dichiarare come tipo l'interfaccia diventa vincolante per la 
classe derivata, tanto che significa perdere qualsiasi miglioria apportata 
dalla classe derivata
 
Enrico
P.S. Giusto per fugare ogni dubbio, il discorso si applica anche alle classi 
di tipo abstract?

 classi di tipo abstract?
 
Vale per tutta l'ereditarietà, che sia con classi normali, astratte o con 
interfacce!
 
class A {
}
 
class B extends A {
    void onlyB() {
        ...
    }
}
 
A a = new B();
 
// da errore!
a.onlyB();
 
 

 meglio usare direttamente la classe derivata :D
 
Guarda che, come ti sta dicendo Vito De Tullio, non centra nulla con le 
interfacce ma si chiama downcasting (o upcasting viceversa) ed e' il 
modo in cui funzionano tutti i linguaggi a oggetti, "duck typing" a 
parte come il python.

 dalla classe derivata
 
Non capisco il problema. Se hai deciso di passare l'interfaccia ad un 
oggetto client, significa che vuoi rendere disponibili unicamente quei 
metodi. Si chiama interfaccia per questo.
 
Invece si può criticare la sintassi: effettivamente
 
if (implementante is Implementante) {
   implementante.setAnotherName("...");
}
 
è meglio di tutte quelle parantesi. Ma si sa che Java è un linguaggio 
piuttosto verboso.
 

 metodi. Si chiama interfaccia per questo.
 
Il fatto e` che volevo usare questo "trucco" per gestire n classi identiche 
per un subset di istruzioni, ma che comunque avessero la possibilita` di 
implementare metodi pubblici aggiuntivi rispetto a quelli esposti 
dall'interfaccia. In definitiva, presumevo di poter usare una sorta di duck 
typing senza dover ricorrere a trucchi ancora piu` sporchi
 
Enrico

 interfacce
 
Veramente io mi riferivo alla sintassi proposta :D
 
Enrico

 oggeti List!
 
Beh, all'epoca dovetti scrivere un client con Java 1.3, ma sinceramente non 
ricordo quanti spargimenti di sangue subii. Piu` che altro, ad un certo 
punto della mia carriera di programmatore, mi sono abituato ad usare 
linguaggi piu` dinamici (Python) rispetto a Java e tornare ad essere legato 
a certi concetti e` come subire un piccolo trauma
 
Enrico


Mah, dovrei vedere il codice per capire se si può riarrangiare ala Java.
 
Tra l'altro non ho mai capito il beneficio del duck typing, cioè dico, 
ma davvero l'avere in comune un nome di un metodo ci dice qualcosa 
riguardo alla semantica della classe?

 Enrico
 
Innanzitutto non vedo cosa ci sia di strano in un cast (upcasting in 
questo caso):
istanzaDerivata = (ClasseDerivata)istanzaBase;
E' identico in C++ o in ObjectiveC.
 
Poi soprattutto in questo thread non si capisce nulla perche':
1) non si capisce perche' hai scritto:
Interfaccia implementante;
implementante = new Implementante();
invece di scrivere:
Implementante implementante;
implementante = new Implementante();
 
2) non si capisce perche' hai voluto usare una interfaccia e non un 
normale classe:
public class ClasseBase {
...
}
public class ClasseDerivata extends ClasseBase {
...
}
e quindi:
ClasseDerivata cd = new ClasseDerivata();
 
Sei stato poco chiaro e hai ottenuto risposte poco chiare.

 riguardo alla semantica della classe?
 
Piu` che altro il mio uso del duck typing e` "bastardo", ovvero creo due 
classi identiche per certi metodi e poi le differenzio per alcuni metodi. Al 
momento di inizializzarle, uso i metodi specifici della classe, mentre 
successivamente uso i metodi comuni. In questo modo non ho problemi di 
capire chi e` che sta facendo cosa, ma per certo so che puo` fare quella 
cosa
 
Enrico

 verranno utilizzati solo i metodi comuni
 
 
Puoi inizializzare dentro il costruttore, oppure usare FileOperation 
dentro lo switch:
 
case "file":
     return new FileOperation(this.cfg).setAnotherInput(anotherInput);
 
non vedo problemi qua.

 dentro lo switch:
 
Si, ci ho pensato pure io dopo aver scritto :)
 
Enrico

 Sei stato poco chiaro e hai ottenuto risposte poco chiare.
 
Non mi sembra, visto che ho chiesto "Si puo` fare X?" e mi e` stato risposto 
"No, non si puo` fare, devi fare Y"
 
Enrico

 riguardo alla semantica della classe?
 
Tecnicamente nemmeno la signature ci dice molto. Se non che il valore di
ritorno ha un certo tipo: tipicamente pero' non e' informazione
sufficiente per specificare completamente la semantica della classe.
 
-- 
-riko
http://www.enrico-franchi.org/
 
http://rik0-techtemple.blogspot.com/