Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Ins$tu' for informa$kk
INF1010 våren 2014 Onsdag 22. januar
Grensesnitt
Stein Gjessing Institutt for informatikk
Ins$tu' for informa$kk
Dagens tema
n Norsk: Grensesnitt n Engelsk: Interface
n Les notatet “Grensesnitt i Java” av Stein Gjessing
n Det finnes haugevis med litteratur om grensesnitt i Java, men mye av det forutsetter at du har lært om subklasser først (innkludert ”Rett på Java”) . Derfor er det kanskje lurt å vente med å lese andre kilder til du har lært om subklasser (i februar).
2
Ins$tu' for informa$kk
3
Hva er objektorientert programmering ? Hva er et objekts grensesnitt mot omverdenen? Svar: De “public” metodene.
3
public void settInn(int tall)
public int taUt( )
Ukjente private data og ukjente private metoder
Ukjent implementasjon av metode
Ukjent implementasjon av metode
F.eks:
Dette er IKKE nytt.
Ins$tu' for informa$kk Hva er objektorientert programmering ? n F.eks: En sort boks som tar vare på tall
4
public void settInn(int tall)
public int taUt( )
Ukjente private data
Ukjent implementasjon av metode
Ukjent implementasjon av metode
Dette kaller vi metodenes signatur
• Metoden “settInn” gjør at objektet tar vare på tallet som er parameter til metode.
• Metoden “taUt” sletter fra objektet et av de tallene som tidligere er satt inn. Metoden returnerer det tallet som slettes.
Dette med semantikk har du kanskje ikke hørt om før!
Dette kaller vi metodenes semantikk
Ins$tu' for informa$kk
5
Hva er objektorientert programmering ?
“public”-metoder definerer objektets grensesnitt mot omverdene Men dette vet vi jo allerede (?) Ja, men det finnes også noe annet som kan gi enda mer vekt på et objekts grensesnitt
Ins$tu' for informa$kk
6
public void settInn(int tall)
public int taUt( )
interface Heltallsbeholder { public void settInn(int tall); public int taUt( );
}
Med Java koden under kan vi senere lage objekter med slik oppførselen
new Heltallsbeholder()
Java kode
Nytt Java-nøkkelord:
interface
Ins$tu' for informa$kk
7 7
interface Heltallsbeholder { public void settInn(int tall); public int taUt( );
}
class MinHeltallsbeholder implements Heltallsbeholder { < (privat) Java datastruktur >
public void settInn(int tall) { < Java kode >
}
public int taUt( ) { < Java kode > }
}
public void settInn(int tall)
public int taUt( )
public void settInn(int tall)
public int taUt( ) kode
datastruktur
kode
Objekt av klassen MinHeltallsbeholder
Da kan vi lage en klasse som vi kan lage objekter av:
En tankemodell av et mulig senere objekt
new MinHeltallsbeholder() gir dette objektet:
Nytt Java nøkkelord: implements!
Ins$tu' for informa$kk
8
interface Heltallsbeholder { public void settInn(int tall); public int taUt( );
}
class EnkelHeltallsbeholder implements Heltallsbeholder { private int tallet = -1;
public void settInn(int tall) { tallet = tall; } public int taUt( ) { int temp= tallet; tallet = -1; return temp; }
} class MegetEnkelTestAvBeholder { public static void main (String[] argumenter) {
EnkelHeltallsbeholder beholder = new EnkelHeltallsbeholder(); beholder.settInn(17); if (beholder.taUt() == 17) System.out.println (“Riktig”); else System.out.println(“Feil”);
} }
public void settInn(int tall)
public int taUt( )
public void settInn(int tall)
public int taUt( )
tallet
Objekt av klassen EnkelHeltallsbeholder
Navn: beholder Type: EnkelHeltallsbeholder
En tankemodell av et mulig senere objekt
FULLSTENDIG KJØRBART PROGRAM
Ins$tu' for informa$kk
9 9
interface Heltallsbeholder { public void settInn(int tall); public int taUt( );
}
class EnkelHeltallsbeholder implements Heltallsbeholder { private int tallet = -1;
public void settInn(int tall) { tallet = tall; } public int taUt( ) { int temp= tallet; tallet = -1; return temp; }
} class MegetEnkelTestAvBeholder { public static void main (String[] argumenter) {
Heltallsbeholder beholder = new EnkelHeltallsbeholder(); beholder.settInn(17); if (beholder.taUt() == 17) System.out.println (“Riktig”); else System.out.println(“Feil”);
} }
public void settInn(int tall)
public int taUt( )
public void settInn(int tall)
public int taUt( )
tallet
Objekt av klassen EnkelHeltallsbeholder
Navn: beholder Type: Heltallsbeholder
FULLSTENDIG KJØRBART PROGRAM
En tankemodell av et mulig senere objekt
Ins$tu' for informa$kk
10
class EnkelHeltallsbeholder implements Heltallsbeholder {
private int tallet = -1; public void settInn(int tall) {
tallet = tall; } public int taUt( ) {
int temp= tallet; tallet = -1; return temp;
} }
interface Heltallsbeholder { public void settInn(int tall); public int taUt( ); }
Kompilatoren sjekker at implementasjonen har
de riktige metodene med de riktige parameterene!
MEN:!Bare du, som er et
menneske, kan sjekke at implementasjonen
overholder de SEMANTISKE KRAVENE !
til metodene. !
• Metoden “settInn” gjør at objektet tar vare på tallet som er parameter til metoden.
• Metoden “taUt” sletter fra objektet et av de tallene som tidligere er satt inn. Metoden returnerer det tallet som er slettet.
Ins$tu' for informa$kk
11 11
public void settInn(int tall)
public int taUt( )
De sematiske kravene kalles også en “kontrakt” (mellom brukerene av objektet og objektet selv)
Institutt for informatikk har 12 forskningsgrupper. En av disse heter “Presis Modellering og Analyse” (PMA). Her arbeider de bl.a. med å formalisere disse sematiske kravene, slik at du kan få hjelp av datamaskinen til å sjekke at implementasjonen overholder de sematiske kravene. Litt mer på en senere forelesning.
Ins$tu' for informa$kk Med Javadoc
12
/** Objektene av alle klassene som implementerer dette gresesnittet tar vare * på heltall. * * @author Stein Gjessing * versjon 10. februar 2012 */ interface Heltallsbeholder { /** * Gjør at objektet tar vare på tallet som er parameter til metoden * *@param tall tallet som objektet skal ta vare på */
public void settInn(int tall); /** * Sletter fra objektet et av de tallene som tidligere er satt inn. * Metoden returnerer det tallet som er slettet. * *@return tallet som er slettet */ public int taUt( ); } Filen Heltallsbeholder.java
Ins$tu' for informa$kk
13
Ins$tu' for informa$kk Kaniner og kaninbur
14
class Kanin{ String navn; Kanin(String nv) {navn = nv;}
} interface KaninOppbevaring {
public boolean settInn(Kanin k); public Kanin taUt( );
} class Kaninbur implements KaninOppbevaring {
private Kanin denne = null; public boolean settInn(Kanin k) { if (denne == null) { denne = k; return true; } else return false; } public Kanin taUt( ) { Kanin k = denne; denne = null; return k; }
}
Ins$tu' for informa$kk
15
Class LittTestKaninbur { public static void main (String [ ] args) { KaninOppbevaring detGuleBuret = new Kaninbur( );
Kanin kalle = new Kanin("Kalle"); Kanin sprett = new Kanin(”Sprett”); detGuleBuret.settInn(kalle); booelan settInnOK = detGuleBuret.settInn(sprett); if (settInnOK) { System.out.prinln(“Feil 1”); } else {System.out.prinln(“Riktig 1”); } Kanin enKanin = detGuleBuret.taUt( ); if (enKanin.navn.equals(“Kalle”) { System.out.prinln(“Riktig 2”); } else {System.out.prinln(“Feil 2”); } detGuleBuret.settInn(sprett); KaninOppbevaring detStoreBuret; detStoreBuret = new Kaninbur(); Kanin trofast = new Kanin("Pelle"); detStoreBuret.settInn(trofast); // bytt kaninene i de to burene: Kanin forstUt = detGuleBuret.taUt( ); Kanin utAvStore = detStoreBuret.taUt( ); detStoreBuret.settInn(forstUt); detGuleBuret.settInn(utAvStore);
. . . . . } }
Kalle
Pelle
Sprett
Ins$tu' for informa$kk
16
boolean settInn (Kanin den)
Kanin taUt( )
Type: Kanin
Navn: denne
Objekt av klassen Kanin
Objekt av klassen Kaninbur implements KaninOppbevaring
. . . . . . . . . .
public static void main ( . . . ) { KaninOppbevaring detGuleBuret = new Kaninbur( ); Kanin kalle = new Kanin("Kalle"); detGuleBuret.settInn(kalle); KaninOppbevaring detStoreBuret; detStoreBuret = new Kaninbur(); Kanin trofast = new Kanin("Pelle"); detStoreBuret.settInn(trofast); . . . . detStoreBuret.taUt( ); . . . }
Type: KaninOppbevaring
Navn: detStoreBuret
Type: Kanin
Navn: kalle
Kanin taUt( )
Type: Kanin
Navn: denne
Objekt av klassen Kaninbur implements KaninOppbevaring
. . . . . . . . . .
Type: KaninOppbevaring
Navn: detGuleBuret
Objekt av klassen Kanin
Type: Kanin
Navn: trofast
class Kaninbur implements KaninOppbevaring {
. . . . }
Felles: class Kanin og interface KaninOppbevaring
Ins$tu' for informa$kk
17
public boolean settInn(Kanin den)
public Kanin taUt( )
En tankemodel for gresesnittet KaninOppbevaring
Men objektene kan gjerne ha andre metoder i tillegge "(kunne spille andre roller også)"(mye mer om dette i februar)"
. . .
• Hvis objektet er tomt vil metoden “settInn” gjøre at objektet tar vare på kaninen som er parameter til metoden, og metoden returnerer sann. Hvis objektet allerede inneholder en kanin gjør metoden ingen ting med objektet, og metoden returnerer usann.
• Metoden “taUt” tar ut kaninen som er i objektet og returnerer en peker til denne kaninen. Metoden returnerer null hvis objektet allerede er tomt..
Et objekt av en klasse som implementerer grensesnittet Kaninoppbevaring
Et grensesnitt beskriver en rolle som alle objektene som implementerer dette grensesnittet må kunne spille"
Semantikk: Signaturer:
public boolean settInn(Kanin den)
public Kanin taUt( )
Ins$tu' for informa$kk
18
class KaninburMedLys implements KaninOppbevaring { private boolean lys = false; private Kanin denne = null; public boolean settInn(Kanin k) { if (denne == null) { denne = k; return true; } else return false; } public Kanin taUt( ) { Kanin k = denne; denne = null; return k; } public void tennLyset ( ) {lys = true;} public void slukkLyset ( ) {lys = false;}
}
Men objektene kan gjerne ha andre metoder i tillegge "
interface KaninOppbevaring { public boolean settInn(Kanin k); public Kanin taUt( );
}
Ins$tu' for informa$kk
19
boolean settInn (Kanin den )
Kanin taUt ( )
void slukkLyset( )
Objekt av klassen KaninburMedLys implements KaninOppbevaring
Type: boolean
void tennLyset( )
Navn: lys
Type: Kanin
Navn: denne
Type: KaninburMedLys
Navn: nyttBurLys
Type: KaninOppbevaring
Navn: detNyeBuret
Objekt av klassen Kanin
interface KaninOppbevaring { public boolean settInn(Kanin k); public Kanin taUt( );
}
Vi kan se på objektet både
med"KaninburMedLys-
briller !og med"
KaninOppbevaring"-briller !
Forskjellige briller = forskjellige roller
Ins$tu' for informa$kk
20
interface KanBjeffe{ void bjeff(); } interface Utkledd { int antallFarger(); } class Karnevalshund implements KanBjeffe, Utkledd { private int farger; Karnevalshund (int frg) {
farger = frg; } public void bjeff( ) { System.out.printl(”Voff - voff”); }
public int antallFarger() { return farger; }
}
Foto: AP
En klasse – mange grensesnitt
Ins$tu' for informa$kk Karnevalshund passopp = new Karnevalshund( ): KanBjeffe gneldrebikkje = passopp; Utkledd godHunden = passopp;
21
void bjeff ( )
int antallFarger( )
Type: int Navn: farger
Objekt av klassen Karnevalshund
{System.out.printl(”Voff - voff”);}
{return farger;}
Type: Karnevalshund
Navn: denne
Type: KanBjeffe
Navn: gneldrebikkje
Type: Utkledd
Navn: godHund
Vi ser på objektet med tre forskjellige briller rolle = brille
KanBjeffe rollen
Utkledd rollen
Ins$tu' for informa$kk Et eksempel til:
22
interface KanBjeffe{ void bjeff(); } interface Svigermor{ boolean oKPaaBesok(); } class NorskSvigermor extends KanBjeffe, Svigermor {
boolean hyggelig = false; public void bjeff( ) { System.out.println(”Uff – uff”); }
public boolean oKPaaBesok() { return hyggelig; }
} Oppgave: Tegn opp et objekt av klassen NorskSvigermor og tre pekere av forskjellig type. Hvilke roller kan dette objektet spille ? Hva ser vi ved hjelp av de forskjellige pekerene?
Ins$tu' for informa$kk
23
Forskjellig klasser – samme grensesnitt
23
interface Skattbar{ // Skatt på importerte varer int skatt(); } class Bil implements Skattbar{ // Bil: 100% skatt
private String regNr; private int importpris; Bil (String reg, int imppris) { regNr = reg; importpris = imppris; } public int skatt( ){return importpris;} public String hentRegNr( ) {return regNr;}
} class Ost implements Skattbar{ // Ost: 200% skatt
private int importprisPrKg; private int antKg; Ost (int kgPris, int mengde) { importprisPrKg = antKg; antKg = mengde; } public int skatt( ){return importprisPrKg*antKg*2;}
}
Ins$tu' for informa$kk
24
Samlet import-skatt
Skattbar[ ] alle = new Skattbar [100]; alle[0] = new Bil(”DK12345”, 150000); alle[1] = new Ost(20,5000); . . . . . . int totalSkatt = 0; for (Skattbar den: alle) { if (den != null) totalSkatt = totalSkatt + den.skatt(); } System.out.println(”Total skatt: ” + totalSkatt);
Type: Skattbar [ ] Navn: alle
Rollen Skatt Rollen Bil (untatt Skatt)
Rollen Ost (untatt Skatt)
Ins$tu' for informa$kk
25
class GeneriskBeholderTilEn <T> { T denne; public void settInn (T en) { denne = en;} public T taUt ( ) {return denne;}
}
Forrige uke:
interface Beholder <T> { public void settInn (T en); public T taUt ( );
} class GeneriskBeholderTilEn <T> implements Beholder <T> {
T denne; public void settInn (T en) { denne = en;} public T taUt ( ) {return denne;}
}
Nå:
Generisk grensesnitt
Ins$tu' for informa$kk Mer grensesnitt med parametre (Generiske grensesnitt)
26
interface EnkelStorBeholder <E> { public void settInn (E den); public E finnEn( ); public void fjern( );
}
Her ønsker vi å lage et grensesnitt til en beholder som kan ta vare på mange elementer (mange objekter av klassen E). Men hva er sematikken til metodene / til grensesnittet? Hvilken semantikk ønsker vi egentlig? Sammenlign med HashMap.
Ins$tu' for informa$kk
27
class KonkretEnkelStorBeholder <E> implements EnkelStorBeholder<E> { private E [ ] alle = (E [ ] ) new Object [100]; private int antall = 0; public boolean settInn(E det) {
if (antall ==100) return false; alle[antall] = det; antall ++; return true; } public E finnEn( ) { if(antall == 0) return null; return alle[antall-1]; } public void fjern( ) { if(antall != 0) antall -- ; }
} 27
navn: alle
type: E[]
navn: antall
type: int 7
settInn
finnEn
fjern
Slike objekter finnes ikke (må gi E en verdi først)
Oppgave: Beskriv sematikken til metodene / til klassen
Ins$tu' for informa$kk
28
EnkelStorBeholder<KarnevalsHund> mittStoreHundehus = new KonkretEnkelStorBeholder<KarnevalsHund> ( ); KarnevalsHund fido = new KarnevalsHund(7); mittStoreHundehus.settInn(fido); KarnevalsHund passopp = new KarnevalsHund(4); mittStoreHundehus.settInn(passopp); KarnevalsHund enHund =
mittStoreHundehus.finnEn( ); if (enHund == fido || enHund == passopp)
System.out.println(”Riktig 1”); else System.out.println(”Feil 1”);
KarnevalsHund trofast = new KarnevalsHund(5); mittStoreHundehus.settInn(trofast); KarnevalsHund sjuklingen =
mittStoreHundehus.finnEn( ); mittStoreHundehus.fjern( ); . . . .
navn: alle type: KarnevalsHund[]
navn: antall
type: int 3
settInn(KarnevalsHund det)
KarnevalsHund finnEn( )
void fjern( )
fido
passopp
trofast
Oppgave: Lag et kaninbur med plass til 100 kaniner