Avatar billede gertnissen Nybegynder
25. maj 2001 - 16:36 Der 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)
Avatar billede mpultz Nybegynder
25. maj 2001 - 16:45 #1
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.
Avatar billede bearhugx Nybegynder
25. maj 2001 - 16:49 #2
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)

*håber det var et tilfredsstillende svar*

/Søren Munk Skrøder



Avatar billede mpultz Nybegynder
25. maj 2001 - 16:50 #3
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.
Avatar billede gertnissen Nybegynder
25. maj 2001 - 16:52 #4
ok, så langt er jeg med.

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 ?
Avatar billede mpultz Nybegynder
25. maj 2001 - 16:58 #5
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).
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:00 #6
For, som sagt, at garantere over for andre klasser, at din klasse vitterligt har implementeret disse metoder ....

forstil dig klasserne Bog og Skilt...
De har forskellige atributter - og de er ikke forbundet via nogen superklasse...

forestil dig så en anden klasse, Læser, som har en metode som hedder læs(...)

Vi ved alle at man kan læse en bog og man kan læse et skilt... Hvordan gør vi så Læser\'en opmærksom på at han kan læse begge \'typer\'....

Svar : ved at klassen Bog og Skilt begge implementere interfacet Læsbar, som f.eks. har en metode, som hedder String getTekst()

så kommer koden til at se sådan ud:

class Bog implements Læsbar
{
....

String getTekst()
{
  Heri føres det læsbare materiale over i en string
}
....
}

class Skilt implements Læsbar
{
....

String getTekst()
{
  Heri føres det læsbare materiale over i en string
}
....
}


class Læser
{

  void læsNoget( Læsbar kilde )
  {
    String detLæste = kilde.getTekst();
  }

}


*et længere, men forhåbentligt fyldigere svar...*

/Søren Munk Skrøder
Avatar billede mpultz Nybegynder
25. maj 2001 - 17:01 #7
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.
Avatar billede gertnissen Nybegynder
25. maj 2001 - 17:06 #8
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 ?
Avatar billede mpultz Nybegynder
25. maj 2001 - 17:08 #9
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.
Avatar billede gertnissen Nybegynder
25. maj 2001 - 17:09 #10
abstrakte klasse kan jeg forstå - de kan i det mindste indeholde noget kode, der kunne lokke mig til at anvende/arve dem.

Men Interfacet, what about Interfacet - what in it for me. (udover det \'kontraktlige\' i specifikationerne)
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:10 #11
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

Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:12 #12
Hovsa... den kom vist igennem uden korrektur....

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
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:16 #13
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)

/Søren
Avatar billede mpultz Nybegynder
25. maj 2001 - 17:23 #14
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.
Avatar billede gertnissen Nybegynder
25. maj 2001 - 17:24 #15
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 ?


Avatar billede mpultz Nybegynder
25. maj 2001 - 17:24 #16
Så Java interfaces er vel egentlig kun til stede fordi Java ikke har multiple inheritance.
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:25 #17
Ja !
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:25 #18
mpultz ... Det er der skam nogen der siger :-) .....
Avatar billede gertnissen Nybegynder
25. maj 2001 - 17:28 #19
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 ?
Avatar billede mpultz Nybegynder
25. maj 2001 - 17:31 #20
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.
Avatar billede gertnissen Nybegynder
25. maj 2001 - 17:35 #21
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

?
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:36 #22
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...

/Søren
Avatar billede bearhugx Nybegynder
25. maj 2001 - 17:42 #23
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....

/Søren Munk Skrøder

Avatar billede mpultz Nybegynder
26. maj 2001 - 10:01 #24
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.
Avatar billede bearhugx Nybegynder
27. maj 2001 - 13:35 #25
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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester