25. maj 2001 - 16:36Der er
23 kommentarer og 2 løsninger
Hvorfor implementere Interfaces ?
Når man implementerer et Interface forpligter man sig til at implementere de metoder der blot er defineret med signaturer i selve Interfacet/Klassen.
Men hvorfor skal man omkring Interfacet ? Kunne man ikke bare implementere metoderne direkte med de korrekte signaturer ? (uden at implementere Interfacet)
Interfacet har jo ingen krop og tilfører dermed ingen funktionalitet til min klasse ? (eller hvad, ligger der noget \'skjult\' i et Interface ?)
Udover at Interfacet er en kontrakt om klassedesign, hvorfor bruger man dem så ?
Ved trådning kan man enten extende THREAD eller implementere RUNABLE. Begge giver mulighed for at støbe en ny tråd. Hvorfor virker de begge ?
(Hvis der kommer flere gode svar, smider jeg naturligvis flere point i)
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Interfaces bruges til skjule implementationsdetaljer. Lad os f.eks. tage RMI (Remote Method Invocation) som eksempel. Her snakker en klient og en server sammen. Klienten kender til interfacet til serveren men er lige glad med implementationsdetaljerne. Serveren derimod implementerer interfacet.
Du kan sammenligne Java interfaces med en header fil i C/C++.
I Java kan du kun arve fra en klasse og brug af interfaces er en måde hvorpå man kan \"simulere\" multiple inheritance. Lad os tage Thread klassen som eksempel. Lad os sige du har lavet et klasse hierarki. Nu vil du gerne have dine underklasser til at operere som tråde. Det er ikke muligt at arve fra Thread da du allerede arver fra din egen superklasse. Men din underklasse kan implementere Runnable og derved agere som en tråd.
Som du selv siger er Interface en \'kontrakt\' omkring klassen.
En klasses atributter arbejder omkring de data, som klassens skal modelere - klassens metoder derimod arbejder omkring klassens adfærd.
At implementere et interface er en \'sikring\' til andre klasser, at denne klasse _garanteret_ har implementeret et bestemt sæt metoder...
Dette betyder at du kan arbejde med klasser - ikke udfra hvilken Type klassen skal modelere (f.eks. Bog) - men udfra klassens _ADFÆRD_ (f.eks. Læsebar, som også kan betyde f.eks. skilt).
Man siger, at denne \'metode-kontrakt\' bruges for at modelere en pseudo-multibel-arv, som er tilgængelig i andre programmeringssprog (f.eks. C++), men som ikke er lovligt i JAVA.
At man udover Thread også har lavet interfacet Runnable (som også implementeres af Thread, btw) er at man også får mulighed for at realisere sub-klasse-tråde (hvis alle tråde skulle (og kun kunne) arve fra Thread, ville der ikke være meget OO tilbage)
Lidt mere til RMI eksemplet. Lad os sige der findes flere servere men deres implementation er forskellig. Ved at bruge interfaces behøver klienten ikke bekymre sig om at implementationen er forskellig, da interfacet er det samme.
Men med arv - arver jeg jo implemterede metoder, ved at implemetere et Interface får jeg blot signaturene for hvordan metoder skal se ud - selve metode kroppen skal jeg selv skrive.
Når jeg selv skal skrive hele metoden, hvorfor så implementere interfacet ?
Et andet eksempel er JDBC. Connection, PreparedStatement og Statement er alle interfaces. Grunden er at den underliggende implementation (JDBC driveren) ideelt set skal være en stort boks for programmøren. Producenter af JDBC drivere implementere JDBC standarden (altså bl.a. ovennævnte interfaces).
På mange måder kan du tænke på et interface som en \"pure\" abstrakt klasse, altså en klasse som ikke kan eksistere \"alene\" og hvor nedarvede klasser skal implementere et antal metoder.
Er det rigtigt at konkludere at Interfacet alene bruges for at \'fortælle\' omverdnen at min klasse følger de specifikationer der er listet i Interfacet via metode-signaturerne ?
Men så må det også betyder at jeg kunne lade være med at implemente et Interface (hvis jeg ønskede) og selv skrev/implementerede metoderne (som er magen til det interface jeg ikke har implementeret) ?
Et ja/nej spørgsmål - Et Interface er alene en kontrakt for implementering og har ingen andre fordele/bennefits ?
Har du nogensiden arbejdet med Clonable interfacet? Hvis en klasse implementerer dette interface fortæller det \"omverdenen\" at det må kopieres (kalde clone() på en instans af klassen). Typisk vil man have flere klasser der kan kopieres, altså impl. Cloneable, men deres indhold og kopieringsmetoder er forskellige. Men Cloneable gør at du kan se \"ens\" på alle objekter som må kopieres.
Ja... men f.eks. i det forige \'Læsbar\'-eksempel ville du i Læser-klassen blive nød til at lave en metode for hver type du ville læse fra... f.eks. void læsNoget( Bog bog) {...} void læsNoget( Skilt skilt) {...} /Søren
I mit forige svar er det nye eksempel baseret på at du i Skilt og Bog-klasserne IKKE implementerer Læsbar-interfacet.... Det nåede jeg vist ikke at skrive... /Søren Munk Skrøder
Det skal dog kommenteres at der også findes (hvad skal man kalde dem...) pseudo-interfaces, som ikke diktere at et sæt metoder skal implementeres...
Et eksempel er Serializable-interfacet, som ikke har nogen metode... I denne forbindelse bruges interfacet til at beskrive at denne klasse kan serialiseres (dvs. gøres persistent, f.eks. på disk)
Nu er de interfaces vi snakker om jo Java specifikke. I C++ har du dem ikke, men du behøver dem heller fordi du har multiple inheritance. Her er en \"pure\" abstrakt klasse \"lig med\" et Java interface.
ahaaa, noget begynder at dæmre (hedder det ikke sådanne ?)
void læsNoget( Læsbar kilde )
Ved hjælp af Interfacet kan jeg kalde læsNoget med et objekt af type læsbar (dvs. f.eks. bog og skilt) og jeg vinder dermed noget kode der er lettere at skrive/vedligeholde. Uden Interfacet skulle jeg lave flere metoder (polymorfi ?) for at kunne løse samme opgave tilsvarende - korrekt ?
Hvis jeg havde implementeret metoden getTekst i både bog og skilt så skulle jeg lave 2 metoder i class Læser, der tog henholdsvis typen bog-class og skilt-class - korrekt ?
I forbindelse med Interfaces og multipel arv angives ofte at multipel arv er problematisk i de tilfælde hvor 2 arvet klasser har 2 præcis intentiske metoder (deres signaturer) for hvilken metode arver man ! - Vil samme problem ikke kunne opstå i Java med Arv og flere Interfaces ?
Nej, du vinder ikke noget ved at bruge interfaces fremfor arv (udover altså at du så ikke kan arve fra andre klasser i Java, men forståelsesmæssigt er det det samme). Ekemplet hvor Læsbar er en abstrakt klasse og bog og skilt arver fra læsbar er ækvivalent med interface eksemplet, forståelsesmæssigt.
Tak til jer begge, jeg tror at jeg nu har bedre forståelse for det smarte i Interfaces (udover det kontraktlige)
mpultz - blot for at være helt sikker
I bearhugx eksempel bruges interfaces og I mit eksempel prøver jeg at forklare mig selv fordelen ved at omskrive eksemplet til at bruge et abstrkt interface
Mener du f.eks. Klasse Test implementerer Interface Læsbar som har en metode getText() Interface TextHolder som har en metode getText() ????
i så tilfælde gør det ikke noget da klassen Test aligevel skal implementere en metode getText() ... Ikke bare ét interface, men nu to dikterer klassen til at dette skal gøres.
Men det er spekulation, da jeg som sagt, aldrig har opblevet at skulle implementere to interfaces med enslydende metoder...
Mpultz >> Ekemplet hvor Læsbar er en abstrakt klasse og bog og skilt arver fra læsbar er ækvivalent med interface eksemplet, forståelsesmæssigt
Tja... Men det betyder også at klasserne Bog og Skilt nu bliver nød til at have \'fælles stamtræ\'....
Og hvadså hvis man opdager andre ting som kan læses....
Jeg kunne f.eks. godt forestille mig at læse en fil class File implements Læsbar {...} men jeg ville _ALDRIG_ putte en fil, et skilt og en bog i samme stamtræ - bare fordi de har fælles absrakt adfærd....
bearhugx: <men jeg ville _ALDRIG_ putte en fil, et skilt og en bog i samme stamtræ - bare fordi de har fælles absrakt adfærd....>
Jeg vil højst sandsynligt heller ikke gøre det i Java, her vil jeg bruge et interface, da Java ikke har multiple inheritance. Min pointe er bare at det OOD mæsssigt intet er i vejen for at have Læsbar som en abstrakt superklasse.
nææ... ikke i sprog som understøtter Multible Inheirit (bruger det selv i C++) ... men nu er det jo java, så der bliver vi nød til at sjusse os lidt frem :-)
(Jeg er dog stadig en stor tilhænger af <<interface>>-stereotypen når det gælder om at \'samle\' forskellige klasser under én hat, baseret på fælles abstrakt adfærd :-)
/Søren
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.