Le interfacce sono delle classi astratte in cui tutti i metodi sono astratti e dove non esistono attributi se non costanti.
Supponi di avere una classe Automobile che definisce tra le altre cose (getBenzina(), getKM(),...) un metodo che "accende" la macchina stessa. Supponi ancora che macchine diverse si "accendono" in modo diverso: la SuperAuto si accende tramite messaggio vocale, mentre la MiniAuto si accende con le chiavi, normalmente.
La SuperAuto e la MiniAuto, sono sempre automobili, quindi è giusto che abbiamo metodi come getBenzina() e getKM()...ma tra loro sono differenti perchè si accendono non nello stesso modo.
Una buona soluzione è quella di dichiarare la classe Automobile come abstract, nonchè il suo metodo accendi() (che nella classe abstract non definiamo).
Questo ci costringe a definire il metodo accendi() nelle classi derivate: ed è proprio quello che vogliamo perchè l'accensione sarà diversa nella SuperAuto e nella MiniAuto....
E fin qui, la classe astratta.
Quando invece dobbiamo definire solo le operazioni che un oggetto deve fare senza dire il come, cioè senza specificarne l'implementazione (ovvero, ancora, se tutti i metodi di una classe dovrebbero essere abstract) allora entrano in gioco le interfacce.
Ad esempio potresti avere una interfaccia che descrive una Lista: allora definirai tutti i metodi che servono per gestira la lista: getNext(), isIn(...), getFirst(...), addElem, deleteElem....ecc
Poichè le liste possono essere implementate in tanti modi, non scriviamo mai l'implementazione di nessun metodo.
Quello che facciamo è definire diverse classi che implementano l'interface Lista e ridefiniscono tutti i metodi (obbligatoriamenti contenuti nell'interface stessa): avremo allora, per esempio, una classe che gestisce le liste tramite array ArrayLista:
codice:
class ArrayLista implements Lista
{
int[]elementi;
....
//implementazione particolare di tutti i metodi contenuti in Lista
}
Oppure ancora possiamo avere una classe che gestisce le liste dinamicamente (liste linkate) e non più con gli array:
codice:
class LinkedLista implements Lista
{
Nodo first;
Nodo current;
Nodo coda;
//implementazione particolare di tutti i metodi contenuti in Lista
}
NOTA Non puoi "istanziare un oggetto di tipo Lista"! Ma puoi scrivere:
codice:
LinkedLista mylist = new LinkedLista(....)....
ArrayLista mylist2 = new ArrayLista(....).....
- ma non:
Lista mylist = new Lista();
....
Per l'ereditarietà multipla:
Java non permette l'ereditarietà multipla in modo esplicito come in altri linguaggi (vedi c++).
Infatti possiamo solo estendere una sola classe padre.
Però possiamo implementare più interfacce...
Quindi se hai due interface I1 e I2 con dei metodi particolari puoi scrivere
codice:
class MyClass implements I1, I2
{
//devi implementare tutti i metodi: sia quelli di I1 che quelli di I2
...
}
Spero di essere stato chiaro e di non aver sbagliato niente :P
Ciao.