// class Bygning Oppgave 1 System.out.println( Bolighus ); // class Bolighus Hva blir utskriften fra dette programmet? class Blokk extends Bolighus{ // class Blokk IN105subclassesII-1 Eksekveringsrekkefølgen (del 1) // class Bygning Til Object sin konstruktør System.out.println( Bolighus ); // class Bolighus class Blokk extends Bolighus{ // class Blokk Her starter eksekveringen IN105subclassesII-3 // class Bygning System.out.println( Bolighus ); // class Bolighus class Blokk extends Bolighus{ // class Blokk Kommentar til oppgave 1 Java føyer selv på disse før programmet eksekveres Dermed får vi utskriften: Bygning Bolighus Blokk IN105subclassesII-2 Eksekveringsrekkefølgen (del 2) Nå er Bygning skrevet ut Nå er Bolighus skrevet ut Nå er Blokk skrevet ut // class Bygning System.out.println( Bolighus ); // class Bolighus class Blokk extends Bolighus{ // class Blokk Tilbake fra Object sin konstruktør Programmet avsluttes IN105subclassesII-4
// class Bygning Oppgave 2 Bolighus (int i) { System.out.println( Bolighus nr + i); // class Bolighus Hva skjer nå? class Blokk extends Bolighus { // class Blokk // class Bygning Oppgave 3 /* Ingen konstruktører */ // class Bolighus Hva skjer her da? class Blokk extends Bolighus { // class Blokk IN105subclassesII-5 IN105subclassesII-7 // class Bygning Kommentar til oppgave 2 Bolighus (int i) { System.out.println( Bolighus nr + i); // class Bolighus Kallet matcher ikke metoden i antall parametre! class Blokk extends Bolighus { // class Blokk Dermed får vi kompileringsfeil. IN105subclassesII-6 Kommentar til oppgave 3 // class Bygning /* Ingen konstruktører */ // class Bolighus class Blokk extends Bolighus { // class Blokk Siden Bolighus ikke har noen konstruktør, legger Java selv inn en tom konstruktør som bare inneholder kallet super(). Dermed får vi skrevet ut Bygning Blokk IN105subclassesII-8
Kort oppsummering Gjenbruk av klasser kan skje ved komposisjon: brukes ved har-en relasjoner arv: brukes ved er-en relasjoner Alle klasser i Java inngår i et hierarki av superklasser og subklasser, med klassen Object på toppen av hierarkiet. Vi skiller mellom typen til et objekt: denne er alltid lik klassen som objektet er en instans av. Kan ikke konverteres (castes). en objektreferanse: denne er lik klassen som objektet er en instans av eller en superklasse av denne. Kan konverteres (castes). IN105subclassesII-9 public, protected og private Ved hjelp av modifikatorer kan vi bestemme hvor synlig en metode skal være utenfor klassen hvor den er definert: private : arves ikke og er ikke tilgjengelig fra andre klasser ingen : arves av alle subklasser i samme pakke og er tilgjengelig fra alle klasser i samme pakke protected : arves av alle subklasser og er tilgjengelig fra alle klasser i samme pakke public : arves av alle subklasser og er tilgjengelig overalt Merk: klassene på et filområde som ikke tilhører noen navngitt pakke, utgjør tilsammen default pakken for det filområdet. IN105subclassesII-11 Kort oppsummering forts. Metoder og variable kan omdefineres i en subklasse. Når vi konverterer en objektreferanse oppover til en superklasse, blir metoder og variable som bare er definert i subklassen usynlige (utilgjengelige). Hvis en metode er definert både i klassen og i en superklasse til et objekt, vil førstnevnte definisjon være den gjeldende, selv når objektet er konvertert til superklassen. Det er ikke alltid mulig å avgjøre ved kompilering hvilken versjon av en metode som faktisk vil bli eksekvert. Dvs vi har dynamisk binding. IN105subclassesII-10 Hvor kan variabelen/metoden ses? Innenfor klassen Innenfor pakken Overalt private ingen protected public = ved komposisjon = ved arv IN105subclassesII-12
Tilgang til variable Ikke la variable være public (pga innkapslingsprinsippet), med mindre de også er final (da kan de uansett ikke endres). private gir større grad av innkapsling (synlig i klassen) enn ingen modifikator eller protected (synlig i pakken). I praksis gir ofte det siste tilstrekkelig beskyttelse, ettersom vi selv gjerne har kontroll over hele pakken. Det sentrale spørsmål blir derfor: ønsker vi at variabelen skal arves (bruk protected) eller ikke (bruk private)? ingen modifikator = protected = public så lenge vi jobber innenfor en pakke (f.eks. den ikke-navngitte default-pakken). IN105subclassesII-13 Når vi jobber innenfor en pakke I In105 legger vi som oftest ikke klasser inn i en navngitt pakke. Dermed jobber vi innenfor en pakke: den ikke-navngitte defaultpakken for det filområdet vi er på. Da er det ingen forskjell mellom public, protected og ingen modifikator (med unntak av main, som må være public) Dvs public og private dekker alle muligheter. IN105subclassesII-15 Tilgang til metoder Er metoden potensielt av interesse for enhver som bruker denne klassen via komposisjon? public Hvis ikke, ønsker vi at metoden skal arves (protected) eller ikke (private)? ingen modifikator = protected = public så lenge vi jobber innenfor en pakke (f.eks. den ikke-navngitte default-pakken). IN105subclassesII-14 Tommelfingerregler Deklarer variable som private Deklarer konstanter som public (hvis nyttige utenfor klassen) Deklarer metoder som public Forøvrig: hvis en metode skal omdefinere en metode i en superklasse, må de ha samme signatur. Husk public når du omdefinerer metoder i API-klasser! programmet vil virke like bra om du erstatter private med ingen modifikator eller med public du kan trygt se bort fra protected i IN105-sammenheng IN105subclassesII-16
Interface Et interface er som en strippet versjon av en klasse: interface InterfaceNavn { metode-spesifikasjoner (navn, argumentlister og returtyper, men ingen implementasjon) Det går ikke an å lage instanser av et interface, bare å implementere det ved å lage klasser av formen class KlasseNavn implements InterfaceNavn { /* Her må alle metodene i interfacet defineres, og kanskje andre metoder og variable også er definert */ Hvis en klasse implementerer et interface, så vil alle dens subklasser også implementere interfacet. Hvis typen til en formalparameter er et interface, kan aktualparameteren være en hvilken som helst klasse som implementerer interfacet. IN105subclassesII-17 Hva er poenget med interface? En måte å se objekt-orienterte programmer på er som kommunikasjon mellom objekter. Objektene snakker sammen via metodekall: set get Et interface angir hvordan du kan snakke til (kommunisere med) et objekt, og intet mer. Typen til objektet spesifiseres ikke. Å implementere et interface er en garanti for at man har visse metoder, dvs at man forstår en bestemt type kommunikasjon. IN105subclassesII-19 Bruk av interface Istedet for å angi nøyaktig hvordan en klasse skal implementeres, er det av og til hensiktsmessig i første omgang å kun angi et interface, f.eks. interface Oversetter { String EngelskTilNorsk (String tekst); String NorskTilEngelsk (String tekst); Enhver klasse som implementerer dette interfacet må definere metodene EngelskTilNorsk og NorskTilEngelsk. Dvs å skrive class MinKlasse implements Oversetter {... er en garanti for at MinKlasse faktisk har to metoder med navn EngelskTilNorsk og NorskTilEngelsk. IN105subclassesII-18 Eksempel public interface Enumerator { public abstract boolean hasmoreelements(); public abstract Object nextelement(); // interface Iterator public class StringTokenizer implements Enumeration { public boolean hasmoreelements() {... public Object nextelement() {... Enumeration /* samt diverse andre metoder */ // class StringTokenizer StringTokenizer IN105subclassesII-20
Abstrakte klasser Nært beslektet med interface er abstrakte klasser. En abstrakt klasse er en klasse med implementasjonshuller som det overlates til subklasser å fylle igjen. En abstrakt klasse deklareres ved å skrive abstract class KlasseNavn { /* variable og metoder, akkurat som for en vanlig klasse. Men noen (eller alle) metoder kan være angitt som i et interface, dvs kun med navn, argumentlister og returtype. Modifikatoren abstract må brukes på disse metodene. */ En abstrakt klasse kan ikke instansieres, bare subklasser av den (som ikke selv er abstrakte). Metoder som er static kan ikke være uimplementerte (abstrakte). IN105subclassesII-21 Hva er poenget med abstrakte klasser? Hvis flere (konkrete) klasser har endel felles egenskaper, er det ofte naturlig å trekke ut disse egenskapene i en egen superklasse, som de andre klassene arver fra. Superklassen representerer da et begrep av mer generell natur enn de tingene man faktisk ønsker å representere som objekter. Dermed er en ofte ikke interessert i å lage instanser av en slik superklasse, bare subklassene. I tillegg er det ofte ikke meningsfylt å gi implementasjoner av metodene i superklassen. Det er da naturlig å deklarere superklassen som abstract. IN105subclassesII-23 Abstrakte metoder Metodene i en abstrakt klasse som er spesifisert, men ikke implementert, kalles abstrakte metoder, og de må deklareres med modifikatoren abstract. Eksempel: abstract class Instrument { abstract void skrivdefinisjon(); // class Instrument class Piano extends Instrument { void SkrivDefinisjon() { System.out.println( Et piano er et strengeinstrument der strengene ); System.out.println( slås an med hamrer ved hjelp av tangenter ); // class Piano IN105subclassesII-22 Sammenlikning Konkret klasse Abstrakt klasse Interface Spesifiserer fullt sett Spesifiserer fullt sett Spesifiserer noen av metoder av metoder metoder for et objekt Implementerer alle Implementerer ingen, Implementerer ingen sine metoder noen, eller alle metoder av sine metoder Kan ha instanser Kan ikke ha instanser Kan ikke ha instanser Kan ha subklasser Må ha subklasser for Kan ikke ha subklasser, å kunne brukes må implementeres IN105subclassesII-24
Flere sett av egenskaper Noen ganger ønsker vi at en klasse skal ha flere sett av egenskaper som er spesifisert annetsteds. Eksempel: en bok i et bibliotek har egenskap av å være E et dokument E et låneobjekt Men Bok kan ikke ha to superklasser Dokument og Låneobjekt (en klasse kan ikke samtidig arve fra mer enn superklasse). Mulig løsning: interface LaaneObjekt {... class Dokument {... class Bok extends Dokument implements LaaneObjekt {... IN105subclassesII-25 Tvilsomt begrepshierarki Dokument Verk Bok CD Video Tidsskriftnr LaanbarBok ULaanbarBok LaanbarCD ULaanbarCD LaanbarTidssk UlaanbarTidssk Flerbindsverk AntikvariskBok Oppslagsverk Antikvarisk tidsskrifnr IN105subclassesII-27 Eksempel: biblioteket igjen Et bibliotek kan inneholde bøker, tidsskrifter, CDer, videoer, mikrofilmet materiale, antikvariske bøker, flerbindsverk, oppslagsverk, upubliserte skrifter, Noen egenskaper finnes hos alle: identifikasjonskode, hylleplass, antall eksemplarer Andre egenskaper finnes bare hos noen: Bøker har forfatter, tittel, forlag Tidsskrifter har årgang, nummer, utgiver CDer har tittel, artist, komponist, musikkforlag Videoer har tittel, regissør, filmselskap IN105subclassesII-26 Omrokkering uten suksess Dokument UtlaanbartDokument UlaanbartDokument Bok CD Video Bok CD Video osv... IN105subclassesII-28
Interface UtlånsObjekt interface UtlaansObjekt abstract void låne(string låner); abstract void levere(); abstract boolean utlånt(); final String ingen = ingen ; Dokument Bok CD Video LaanbarBok ULaanbarBok LaanbarCD ULaanbarCD IN105subclassesII-29 Forenklet bibliotek For å spare plass og tid, ser vi i fortsettelsen på følgende forenklede bibliotek: Utlaansobjekt Dokument Bok CD LaanbarBok ULaanbarBok LaanbarCD ULaanbarCD IN105subclassesII-31 interface = rolle Utlaansobjekt Dokument Antikvarisk Verk Bok CD Video Tidsskriftnr LaanbarBok ULaanbarBok LaanbarCD ULaanbarCD LaanbarTidssk UlaanbarTidssk Flerbindsverk AntikvariskBok Oppslagsverk Antikvarisk tidsskrifnr IN105subclassesII-30 Abstrakte klasser og interface abstract class Dokument { String tittel;... // class Dokument interface UtlaansObjekt { abstract void låne (String låner); abstract void levere (); abstract boolean utlånt (); final String ingen = ingen ; // interface UtlaansObjekt IN105subclassesII-32
Klasser for bok abstract class Bok extends Dokument { String forlag; int trykningsår;... // class Bok class LaanbarBok extends Bok implements LaaneObjekt { String låner = ingen; public void låne (String l) { låner = l; public void levere () { låner = ingen; public boolean utlånt () {return låner!= ingen; /* Andre metoder som gjelder alle bøker */ // class LaanbarBok class ULaanbarBok extends Bok { /* Metoder som gjelder alle bøker */ // class ULaanbarBok IN105subclassesII-33 Klasser for CD abstract class CD extends Dokument { String komponist, artist, musikkforlag;... // class CD class LaanbarCD extends CD implements UtlaansObjekt { String låner = ingen; public void låne (String l) { låner = l; public void levere () { låner = ingen; public boolean utlånt () {return låner!= ingen; /* Andre metoder som gjelder alle CD er */ // class LaanbarCD class ULaanbarCD extends CD { /* Metoder som gjelder alle CD er */ // class ULaanbarCD IN105subclassesII-34