Avatar billede javaknold Nybegynder
14. maj 2003 - 19:44 Der er 28 kommentarer og
1 løsning

Interface problemer

Jeg har aldrig rigtig fattet hvad et interface
er godt for, udover at det kan anvendes
som en slags bro mellem klasser - et eller
andet abstract halløj, men alligevel synes
jeg godt at jeg kunne bruge dem ind imellem

Men nu er kæden hoppet helt af !

Jeg ville se hvad jeg kunne udrette med
følgende metode:    listFiles(FileFilter filter)
fra klassen java.io.File

Men den tager et interface som argument og
så stod jeg af.

Er der nogen som kan fortælle hvordan et
interface generelt anvendes og især i ovenstående
situation ??

Ja - jeg har tæsket adskillige tutorials igennem
uden at have fattet det 100%, men selvfølgelig er
ekstremt gode links velkomne.

Måske har jeg fyret rigelig med points på, men
jeg fatter det bare ikke !!
Avatar billede arne_v Ekspert
14. maj 2003 - 19:50 #1
I den situation og i mange andre situationer er pointen den,
at der skal kaldes med et argument.

Det argument skal være af en klasse som implementerer det
pågældende interface.

Det kan være enhver klasser der implementerer interfacet.

Men fordi Java compileren insisterer på at en klasse der
implementerer et interface skal implementere alle metoder
i interfacet, så ved den metode der kaldes at den kalde alle
metoder i interfacet - selvom der kan være vidt forskellige
implementeringer.
Avatar billede arne_v Ekspert
14. maj 2003 - 19:56 #2
Lad os sige at du laver en klasse som skal bruge noget konfigurations
data, men at du vil være meget fleksibel med hvordan den konfiguration
kan gemmes.

Så laver du:

public interface XConf {
  public int getA();
  public String getB();
}

og i din klasse:

void dosomething(XCong cfg) {
  ...
  int a = cfg.getA();
  String b = cfg.getB();
  ...
}

Så laver du:

public class XConfFile {
  public XConfFile(String filename) {
      // open file
  }
  public int getA() {
      // læs A fra fil
  }
  public String getB() {
      // læs B fra fil
  }


public class XConfDB {
    public XConfDB(String driver, String url, String un, String pw) {
      // open database connection
  }
  public int getA() {
      // læs A fra database
  }
  public String getB() {
      // læs B fra database
  }


og så man kalde din metode med både:
  dosomething(new XConfFile("X.cfg"));
og:
  dosomething(new XConfDB(driver, url, "", ""));

og din metode kan bruge getA og getB uden at vide hvad de faktisk
kalder.

Men interface definerer en kontrakt for hhvad klasserne som minimum skal
kunne.
Avatar billede arne_v Ekspert
14. maj 2003 - 19:57 #3
Jeg ved ikke om det var det bedste eksempel, men det var det bedste
jeg lige kunne komme på.

:-)
Avatar billede arne_v Ekspert
14. maj 2003 - 20:00 #4
Fot at vende tilbage til FileFilter så betyder det at din klasse skal
implementere:

public boolean accept(File pathname) {
}

til at acceptere (eller forkaste filer med).
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:25 #5
Sorry - faldt i staver ved fjerneren, havde ikke kalkuleret med så hurtige svar

Vender tilbage når jeg har tygget dine svar igennem!
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:31 #6
Jeg er med indtil vi når:  public class XConfFile

hvor kommer interfacet ind i billedet her ?
Avatar billede arne_v Ekspert
14. maj 2003 - 20:34 #7
Der skulle naturligvis have stået

public class XConfFile implememnts XConf {

og

public class XConfDB implememnts XConf {
Avatar billede arne_v Ekspert
14. maj 2003 - 20:35 #8
implements

(nej som det går)
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:35 #9
Okay
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:40 #10
Jeg spørg nok om mere end ti tosser kan svare på, men hvordan
hænger nedenstående så sammen med de øvrige klasser (XConfFile, XConfDB) efter implemeteringen af interfacet ?

og i din klasse:

void dosomething(XCong cfg) {
  ...
  int a = cfg.getA();
  String b = cfg.getB();
  ...
}
Avatar billede arne_v Ekspert
14. maj 2003 - 20:45 #11
Pointen er at du nu kan kalde dosomething metoden med både
en XCongFile og en XConfDB, fordi metoden kun forventer en
XConf og begge klassser implementerer XConf.
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:48 #12
Men når variablen 'a' initieres via cfg.getA();
hvordan ved jeg så om det bliver fra XConfFile eller XConfDB

Eller sagt på en anden måde hvad kalder hvad - hvor er udgangspunktet
Avatar billede javaknold Nybegynder
14. maj 2003 - 20:50 #13
Den her er jeg ikke helt med på, viker som noget løst hængende noget jeg ikkke
kan placere.

og i din klasse:

void dosomething(XCong cfg) {
  ...
  int a = cfg.getA();
  String b = cfg.getB();
  ...
}
Avatar billede arne_v Ekspert
14. maj 2003 - 20:53 #14
Det ved du slet ikke når du skriver dosomething.

Men når kode eksekveres så kalder java getA på det objekt der faktisk
er kaldt med.

Så hvis du har kaldt dosomething med en XConfDB så henter den fra
databasen, hvis du har kaldt med en XConfFile så henter den fra fil.

Men beslutningn træffes først når programmet køres - ikke når koden
compiles.

[naturligvis bestemmes det inddirekte når den kode der kalder
dosomething compiles]
Avatar billede javaknold Nybegynder
14. maj 2003 - 21:00 #15
Hvordan kalder jeg eksempelvis:  dosomething med en XConfDB
Avatar billede arne_v Ekspert
14. maj 2003 - 21:03 #16
XConf xcfg = new XConfDB(mindriver, minurl, "mig", "hemmeligt");
dosomething(xcfg);

eller:

dosomething(new XConfDB(mindriver, minurl, "mig", "hemmeligt"));
Avatar billede javaknold Nybegynder
14. maj 2003 - 21:09 #17
Okay - på mig virker det umiddelbart som at gå baglæns gennem verdenen

Kan man virkelig lave en reference til et interface og initiere referencen via et object som implementerer interfacet.
Og derefter bruge den som parameter i et metodekald ?
Avatar billede arne_v Ekspert
14. maj 2003 - 21:14 #18
Ja.

Og det er skam meget praktisk.

Lad os vende tilbage til FileFilter. SUN programmørerne sidder
og skal kode listFiles og de vil gerne give noget af din kode
mulighed for at bestemme om en fil skal med eller ej.

De aner ikke hvordan din kode vil se ud, hvad den vil bruge til at
afgøre om filen skal med, hvad klassen vil hedde.

Men de laver nu et interface FileFilter med en enkelt metode accept.
Nu kan du kalde deres metode med en hvilken som helst klasse der
implementerer FileFilter (og dermed accept metode). Deres kode
kalder bare accept metode som jo skal være der.
Avatar billede arne_v Ekspert
14. maj 2003 - 21:16 #19
Det er rigtigt smart.

Og noget helt fundamentalt i objekt orienteret programmering.

Bruger du JDBC ?

Der er stort set kun interfaces i JDBC næsten ingen klasser !
Avatar billede javaknold Nybegynder
14. maj 2003 - 21:26 #20
Det kan jeg se.

Det havde nu været rart, hvis der i de tutorials jeg har tæsket igennem
var et eksempel a la dit, så man også havde fået den vinkel af interfacets muligheder.

Mange tak for hjælpen.

Jeg skal lige sunde mig inden jeg kører videre med FileFilter - TAK !
Avatar billede javaknold Nybegynder
14. maj 2003 - 21:29 #21
Jeg leger med lidt RMI

Har indtil videre gået langt udenom interfaces, har aldrig rigtigt fattet dem.
Avatar billede arne_v Ekspert
14. maj 2003 - 21:35 #22
I RMI bruger man interfaces til at få følgende til at virke:

client kode--(kald)-->genereret stub kode--(socket)-->genereret skeleton kode--(kald)-->"

hvor pointen er at "genereret stub kode" og "genereret stub kode" har
samme interface.

Det er også det man kalder et proxy pattern.

Man kalder noget lokalt der har samme interface som det man
rellet ønsker at kalde remote.
Avatar billede javaknold Nybegynder
14. maj 2003 - 21:39 #23
Ja, men her synes jeg interfacet virker på en anden måde,
som en BRO mellem client og server classe

Den du lige har hjulpet mig med her, havde jeg aldrig selv gennemskuet !
Avatar billede arne_v Ekspert
14. maj 2003 - 21:45 #24
Både ja og nej.

Det er reelt meget anderledes men ideen i proxy pattern er
faktisk den samme.

Lad os kalde interfaces for Xxx og implementationen for XxxImpl.

Lad os sige at vi har en stor applikation som vi skal have
lavet om til client server med RMI.

Hvis den applikation er lavet som:

Xxx x = new XxxImpl();
x.method1();
...
x.method999();

så kan den lave som til RMI bare ved at ændre en linie og ikke 999 linier:

Xxx x = (Xxx)Naming.lookup("Xxx");
x.method1();
...
x.method999();

ved at bruge interface kan man skifte mellem lokal og remote
implementation i en linie.

Det er det som proxy pattern virkeligt drejer sig om.

I praksis tænker man nok ikke så meget over det når man bare
laver RMI.
Avatar billede javaknold Nybegynder
14. maj 2003 - 22:03 #25
Aha - Jeg kan ikke sige jeg er 100% med, men måske nogenlunde.

Jeg gør sådan:
java.rmi.Naming.rebind("//" + host + "/" + navn, rmiSI);

Hvor rmiSI er min RMIserverImpl.class, som implementerer mit interface

Men lige pt. kan jeg ikke gennemskue om det er det samme.

Til gengæld kan du være 100% sikker på, at jeg vender tilbage hvis det giver mig problemer.
Avatar billede arne_v Ekspert
14. maj 2003 - 22:08 #26
Åh. Det er server side. Mine betragtninger var på client side.
Avatar billede javaknold Nybegynder
14. maj 2003 - 22:10 #27
Tusind tak, arne!
Avatar billede javaknold Nybegynder
14. maj 2003 - 22:21 #28
HALLO - jeg gør rent faktisk sådan

myRMI = (RMIinterface) java.rmi.Naming.lookup( serverObjNavn );

d.v.s. jeg er på den rigtige side af hegnet uden selv at vide det.

Det er jo egentlig perfekt at gøre noget rigtigt uden selv at være klar over det.

Takker for din uddybning af emnet!
Nu kan der vist heller ikke tærskes mere på det idag. - TAK
Avatar billede arne_v Ekspert
14. maj 2003 - 22:23 #29
Ja - det gør alle der bruger RMI.

Fordi det står i diverse bøger og tutorials.

Det der tit mangler er en forklaring på hvorfor man gør det sådan.
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