Hejsan hoppsan!! Främst så är det något du bör tänka på om du skriver kod tillsammans med andra, eller kod som du inte riktigt vet hur du ska skriva än. Jag tycker att du ska vända på din fråga...när lönar det sig INTE att använda interface? :) Nils, Nu är vi verkligen inne och pratar objektorientering. Enligt god objektorienterad princip ska man programmera mot interface och inte direkt mot klasser...det finns skrivet i istort sett alla böcker som behandlar ämnet...finns massor att läsa på nätet och det är ju också det som är grunden för en löskopplad lösning, OO alltså. Ni kan titta under tråden http://www.pellesoft.se/communicate/forum/view.aspx?msgid=148270&forumid=81&sum=0 för ett lite mer komplicerat exempel på när interface kan vara bra att använda.Interface
Nån som har ett bra exempel/förklaring på när det lönar sej att skriva ett Interface? Läste igenom http://java.sun.com/docs/books/tutorial/java/interpack/interfaces.html men tyckte exemplet var lite fattigt..
tackSv: Interface
Alltså; låt säga att du behöver en klass som ska representera något, till exempel nån sorts specialbehållare, "SpecContainer". Du tänker att "jag måste kunna få fram värdet på en viss plats i behållaren, jag måste kunna lägga in värden, och jag måste kunna byta ut värden"
Nån specialvariant där man aldrig kan ta bort ett värde, bara byta ut ett. Däremot har du ingen aning om hur man skulle kunna skriva en sån behållare, och det ger du en anställd i uppdrag. För att den ska fungera precis som du vill skriver du ett Interface.
public interface SpecContainer{
void insertValue (int value);
int getValue (int position);
int changeValue (int position, int value);
}
Där beskriver du alla metoder som en "SpecContainer" ska kunna ha. Vem som helst kan nu skriva ett program som använder en SpecContainer - utan att någon har skrivit kod för hur de grejerna ska funka.
Du kanske skriver
...
void analyzeContainer(SpecContainer sc);
...
Och inuti analyzeContainer så skriver du massa kod för att analysera din container. Där använder du hela tiden insertValue, getValue och changeValue.
Det är så att säga ena sidan av ett interface - de som använder den och skriver metoder som använder den. De behöver aldrig veta nånting annat än just vad det finns för metoder i interfacet.
Andra sidan är de som skriver kod för det. De behöver bara tänka på en enda sak - att skriva klasser som exakt uppfyller det interfacet säger. De måste implementera de olika metoderna, och de måste göra det rätt. De behöver dock inte bry sig ett dugg om vad deras klasser ska användas till.
De kanske kallar sin SpecContainer för MySpec.
Det kan vara ett helt annat företag (eller samma personer, för den delen). På så sätt hålls antalet förbindelser mellan olika klasser nere, och om man någon gång vill byta klass från MySpec till en annan som heter YourSpec (som implementerar samma interface), så är det inga problem, allt är redan anpassat till interfacet.
Sv: Interface
Jag har skrivit lite om interface i tråden "Skicka data, skiktad lösning..." i C# forumet. Där kan du läsa varför jag favoriserar interface.
Jag programmerar alltid mot interface och inte konkreta klasser, t ex Collection c = new ArrayList(), Map m = new HashMap() osv. Interfacedriven utveckling gör att du får ett väldigt löskopplat (losely coupled) system. Det blir enkelt att byta ut tredjepartkomponenter utan att förändra en kodrad i din verksamhetslogik. Titta också på Inversion of Control, t ex på Springframework eller Pico container så kan du också se nyttan av interface.
Jag håller inte riktigt med Niklas när han säger "något du bör tänka på om du skriver kod tillsammans med andra, eller kod som du inte riktigt vet hur du ska skriva än". Om man inte vet hur man ska skriva koden så ska man nog inte skriva den alls utan gå tillbaka till analysfasen ;)
Interface gör helt enkelt livet så mycket enklare. Jag vet inte om du tittat på några command pattern men där ligger ju interface till grund för allt.
Du kan t ex ha ett interface
public interface Action {
void execute() throws Exception;
}
Du kan sedan ha en klass som exekverar dina actions:
public class MyExecuter implements Executer {
public static void doExecute(Action action) throws Exception {
action.execute();
}
}
Du kan sedan göra vad du vill i dina actionklasser, t ex
public class Main {
public static void main(String[] args) {
new Main().go();
}
public void go() {
MyExecuter.doExecute(new MathAction());
}
// inner class
class MathAction implements Action {
public void execute() throws Exception {
System.out.println("5 - 4 = " + (5 - 4));
}
}
}
MyExecuter har inte en aning om vad olika actions gör...det enda den gör är att exekvera dem.
Tja, jag vet inte hur mycket det exemplet säger dig eller hur hemma du är bland command patterns. De används ganska ofta i MVC ramverk som t ex WebWork/XWork.
Du kan också titta på eventhanteringen i java där du måste implemetera listener interface och registrera dessa.
Hoppas att det blev något klarare...om inte så får du höra av dig igen :)
/NilsSv: Interface
Jag lägger denna tråd i skitade tråden, hoppas det är ok, för det kan nog vara intressant för dem som läser om skiten att även få denna mer tekniska förklaring.
Varför gör du Collection c = new ArrayList() och då utföra en casting? hur gör du när du helt plötsligt måste nyttja de unika metoder en ArrayList har som inte finnsi ICollection interfacet?
Jag gör inte som du gör här, då ArrayList och Map faktiskt inte förändrar sig utan håller sina APIer då de i princip baseras på en Standard. Det som dock kan hända är att det kommer till några extra metoder till dem. I de fall jag själv vill hantera min egna Collection brukar jag ärva ICollection och bygga impelemntationen själv, om inte någon redan befintlig struktur klass existerar.
En sak jag tycker är lite tråkigt med struktur klasserna i .Net ramverk är att de inte har Visitor Patterns.
Dock kommer det komma något liknande i många Generic baserade steukturer i C# 2 där du kan skicka in Delegat för att utföra saker med dess innehållande data samling. Jag har fått bygga in Visitor Patterns själv och faktiskt haft god nytta av dem, har du nyttjat dem nått? .Accept(...) är väl den vanligaste signaturen.
Mvh JohanSv: Interface
Johan, när du skriver
"Varför gör du Collection c = new ArrayList() och då utföra en casting?"
blir jag nästan lite rädd...här sker ABSOLUT ingen casting. Och exemplet kan ju vara taget direkt ur vilken OO bok som helst.
Interface ger friheter och gör det enkelt att refaktorera. Tänk dig en metod som returnerar en ArrayList. Tänk dig sedan att det kanske är tre-fyra klasser som använder metoden. Du upptäcker sedan att en ArrayList inte funkar utan du måste ha en Vector för att du vill åt synkronieringen som finns i en Vector. Om din metod då returnerat en ArrayList istället för t ex en Collection (interface) så måste du skriva om din metod + de andra klasserna...inte särskilt bra...en massa onödigt jobb än om du arbetetat mot interface från början. Ändra implementationen men inte interfacet och du slipper koda om på en massa andra ställen...objektorientering at its finest. Och dessutom är det inte särskilt ofta man behöver använda några speciella metoder i t ex ArrayList som inte finns tillgängliga via Collection interfacet. Har aldrig, i stort sett, stött på några som helst sådana fall.
Du skrev också "I de fall jag själv vill hantera min egna Collection brukar jag ärva ICollection och bygga impelemntationen själv, om inte någon redan befintlig struktur klass existerar." Men varför använder du inte interface också med befintliga klasser som finns? Vad tror du ligger bakom tankarna med att låta de flesta klasser du använder i java eller c# implementera någon typ av interface? Jag kan berätta tre av orsakerna för dig...objektorientering, återanvändbarhet och loosely coupled systems som ex.
/NilsSv: Interface
/Nils