Newsgroup: it.comp.java
Titolo: A che servono le interfacce?

Sono un programmatore Java alle prime armi.
Sto leggendo un manuale su come programmare in Java, e sono arrivato al
capitolo che tratta delle interfacce.
Non ho capito una cosa: a che servono le interfacce?
Quando si eredita una classe con "extends" si possono ridefinire alcuni
metodi ma di solito ci sono dei metodi gia' scritti (i metodi
ereditati) che possono essere sfruttati.
Se in una interfaccia TUTTI i metodi devono essere astratti a che serve
implementare l'interfaccia dato che TUTTI i metodi devono essere
ridefiniti?
NON ci sono metodi gia' scritti che possono essere sfruttati.

Bracco Baldo ha scritto:

Devi vedere l'interfaccia come un contratto al quale le tue classi 
debbono sottostare per poter fare qualcosa.... per esempio .... prendi 
l'interfaccia Serializable... ti dice che se vuoi che un oggetto sia 
serializzabile deve esporre i seguenti metodi :
private void writeObject(java.io.ObjectOutputStream out)
      throws IOException
  private void readObject(java.io.ObjectInputStream in)
      throws IOException, ClassNotFoundException;
e quindi l'interfaccia ti garantisce alcune cose se rispetti il suo 
contratto.
ciao
PP

 contratto.
Serializable non definisce alcun metodo in realta': 
http://java.sun.com/j2se/1.4.2/docs/api/java/io/Serializable.html
E' piu' un marcatore per dire che quella classe puo' essere serializzata.

> E' piu' un marcatore per dire che quella classe puo' essere serializzata.
Si è un contratto che la tua classe deve rispettare se vuole essere 
serializzata.... deve implementare  i 2 metodi presenti nell'interfaccia

 serializzata.... deve implementare  i 2 metodi presenti nell'interfaccia
Non e' vero. I 2 metodi devono essere implementati se si vuole gestire 
la serializzazione in modo particolare. Altrimenti serializza ugualmente 
come puo'.

 Non ho capito una cosa: a che servono le interfacce?
Provo con un esempio.
Stai realizzando una applicazione generica.
Questa applicazione ha dell'output. Tu non sai bene quale tipo di output ti
servira'. Potrebbe essere un file, un monitor, una stampante o qualsiasi
cosa.
A questo punto scrivi un interfaccia
"OutputWriter"
che avra' ad esempio il metodo
"write"
Nel tuo programma puoi utilizzare tranquillamente l'interfaccia al posto
delle classi finali che scrivono sui vari device e completi il programma.
Poi ci aggiungi un metodo
setOutputWriter( OutputWriter outputWriter )
{
   this.outputWriter = outputWriter ;
}
e a seconda se vorrai stampare o andare su file o a video passerai il
corretto writer.
Il tuo programma funzionera' potenzialmente per sempre anche se domani
decidi di scrivere in output con un laser in un sasso :-)
Ciao Nicola
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 writes:
BB> Sono un programmatore Java alle prime armi.  Sto leggendo un manuale
BB> su come programmare in Java, e sono arrivato al capitolo che tratta
BB> delle interfacce.
BB> Non ho capito una cosa: a che servono le interfacce?
BB> Quando si eredita una classe con "extends" si possono ridefinire
BB> alcuni metodi ma di solito ci sono dei metodi gia' scritti (i metodi
BB> ereditati) che possono essere sfruttati.
Come ti  hanno detto  una interfaccia stabilisce  un "contratto"  che il
creatore di  una classe  si impegna  a rispettae una  volta che  pone la
dichiarazione "implements". L'effetto  è che chi usa la  classe è sicuro
di poter  fare certe cose con  gli oggetti di quella  classe, ovvero che
quegli oggetti avranno un certo comportamento.
Le  interfacce definiscono  un tipo,  ma senza  definirne i  dettagli di
implementazione (ed in questo sono simili alle classi pure astratte).
Fine sbrodolamento teorico.   Vediamo praticamente quali problemi risol-
vono le interfacce.
Primo uso, stabilire uno standard per chi dovrà scrivere nuovo codice.
Prendiamo  ad esempio  il  package  java.sql che  definisce  le API  per
accedere a  dati immagazzinati in database  o altre fonti  di dati (data
source).
Ora Sun ha scritto le interfacce,  ma sono i produttori dei database che
forniscono le  implementazioni concrete delle interfacce  in quanto sono
loro che sanno come è fatto il loro database.
Ma per  il programmatore  che le  usa non cambia  molto, ad  esempio per
passare dal database della MegliAMano a quello della VedoPrevedoStravedo
o a  quello della MioTuoSuo  dovrà cambiare solo  il nome del  driver da
utilizzare (una stringa).
Per il resto, ad esempio,  gli oggetti (di tipo) Connection si comporte-
ranno come oggetti (di tipo)  Connection ed i ResultSet si comporteranno
allo  stesso  modo,  anche  se  "dentro"  le  implementazioni  dei  vari
produttori saranno diversissime.
Al programma che  usa oggetti appartenenti ad una  classe che implementa
l'interfaccia ResultSet  non importa come  è fatto dentro  l'oggetto che
sta usando, importa solo come si comporta.
Secondo uso,  fare si che un  oggetto appartenga a  più tipi contempora-
neamente.
Ci sono linguaggi in cui una  classe può estendere più classi invece che
una sola. La cosa sembra carina ma se non viene fatta come si deve è una
fonte di guai. Usualmente viene fatta  nel modo "fonte di guai" (vedi il
Gosling per una spiegazione più dettagliata).
Per evitare guai in Java hanno detto che una classe può estendere una ed
una sola classe.
Ma ci  sono casi  in cui  è necessario che  un oggetto  possa presentare
nature diverse.
Supponiamo di scrivere un simulatore ferroviario.
Abbiamo pensato  di aver  bisogno, insieme a  molte altre,  della classe
Locomotiva e la classe Vagone. Un nostro collega ci fa notare che avremo
bisogno  anche della classe  Automotrice che  descrive quei  veicoli che
sono allo stesso tempo sia  Locomotiva che Vagone e dobbiamo poter usare
un'Automotrice  come Locomotiva  quando ad  esempio ci  serve  il metodo
traina(Convoglio), e poterlo usare  come Vagone quando serve, ad esempio
per utilizzare il metodo aggiungi(Vagone) della classe Convoglio.
Dato che in Java non possiamo scrivere 
class Automotrice extends Locomotiva, Vagone
ci tocca trovare una soluzione. 
E la soluzione ce la danno le interfacce. Invece di definire Vagone come
classe, la definiamo come interfaccia.
Avremo quindi
class CarroMerci implements Vagone {}
class CarrozzaPasseggeri implements Vagone {}
class Automotrice extends Locomotiva implements Vagone {}
Terzo  uso, dire  di un  oggetto solo  ciò che  serve. Questo  serve per
l'architettura  dei programmi, in  quanto più  cose dell'oggetto  B sono
note all'oggetto  A, tanto più  l'oggetto A dipenderà dall'oggetto  B, e
questo non è bene.
Tornando al  caso iniziale dei  database.  Se un  programmatore utilizza
delle  classi  che  ci  sono  solo nelle  librerie  del  database  della
VedoPrevedoStravedo che  non sono previste dalle  interfacce del package
java.sql,  allora sarà  molto difficile  fare  si che  il programma  sia
adattato ad usare il database della MeglioAMano o della MioTuoSuoSql.
Non ho detto impossibile, ho detto difficile ovvero costoso.
Altra  situazione, vuoi che  altri programmatori  o parti  del programma
possano interagire  con un certo modello  dati ma non  vuoi che sappiano
come  è effettivamente  fatto il  modello  dati: non  vuoi che  scrivano
codice che  va a "zampettare in  modo improprio" nel modello  dati o che
abbia  delle dipendenze  simili a  quelle che  abbiamo appena  visto con
l'uso  di  classi "speciali"  di  un  certo  database piuttosto  che  di
un'altro.
In questo caso l'interfaccia ti aiuta. Gli altri programmatori/resto del
programma sapranno solo che esistono le cose dichiarate nell'interfaccia
e useranno  solo quelle senza mettere  le mani in  modo pericoloso nella
struttura dati  e permettendoti di cambiarne la  struttura interna senza
danneggiare il  funzionamento dei  programmi che usano  questa struttura
dati.
Credo di aver sbrodolato abbastanza.
-- 
 /\           ___                                    Ubuntu: ancient
/___/\_|_|\_|__|___Gian Uberto Lauri_____               African word
  //--\| | \|  |   Integralista GNUslamico            meaning "I can
\/                   e coltivatore diretto               not install
                               di software                   Debian"
a Cesare avrei detto di scrivermi | I would have told Caesar to write
a 
fn...@rat.vg
                    | me at 
fn...@rat.vg