INF1010 oversikt med Subklasser mm Unntaksbehandling GUI Tråder 20. mai 2010 Stein Gjessing
Model View Control main navn: bnk type: BankKontroll bnk = new BankKontroll(); bnk.ordreløkke(); BankKontrollklassedatastruktur BankUtsyn objekt leskommando beomnavnogbelop hentnavn hentbelop beomoghentnavn skrivsum BankKontroll navn: b type: Bank BankKontroll objekt Bank objekt lagnykunde lagbankkunde KernBankKunde KernBankKunde seminn sumallekoni sumallekoni seminn ordrelokke navn: koni navn: u type: HashMap type: BankUtsyn Konto objekter HashMap objekt 2
Klassehierarki: Personbil Bil Klasser - Subklasser class Bil { <blå egenskaper> class Personbil extends Bil { <røde egenskaper> class Lastebil extends Bil { < mørke røde egenskaper> class Drosje extends Personbil { < gule egenskaper> Alle lastebiler Lastebil Drosje Alle biler Alle drosjer Alle personbiler 3
Konvertering av pekere class cast MasterStudent master = new MasterStudent(); Konvertering oppover: Student stud = master; Person pers = master; Konvertering nedover: Person pers Student stud (Student) pers (MasterStudent) pers (fordi dette krever kontroll under kjøring) MasterStudent master Regel: Objektet som en peker peker på må ha alle egenskapene som typen til pekeren angir Derfor: Alle pekere har lov til å peke bortover og nedover (men ikke oppover ) 4
Konstruktører Superklassens konstruktør kan kalles fra en subklasse ved å si: super(); vil kalle på en konstruktør uten parametre super(5, test ); vil kalle på en konstruktør med to parametre (int og String) Et kall på super må legges helt i begynnelsen av konstruktøren. Kaller man ikke super eksplisim, vil Java selv legge inn kall på super( ) helt først i konstruktøren når programmet kompileres. Hvis en klasse ikke har noen konstruktør, legger Java inn en tom konstruktør med kallet super(); 5
Eksempel Her er fire forslag til konstruktører: Student() { studid = 0; Anta at vi har følgende klasser: class Person { String fødselsnr; Person(String fnr) { fødselsnr = fnr; class Student extends Person { int studid; Student() {... Student() { super( 12345"); studid = 0; Student(String nr){ super(nr); studid = 17; Student(String nr, int id){ super(nr); studid = id; Hvilke virker?
Omdefinering av metoder polymorfi En subklasse kan utvide en eksisterende klasse med nye metoder. En subklasse kan også definere en metode med samme signatur som en metode i superklassen, men med ulikt innhold. Den nye metoden vil omdefinere (erstame) metoden som er definert i superklassen. Metoder som kan omdefineres på denne måten kalles virtuelle metoder. I Java er alle metoder virtuelle, så sant de ikke er deklarert med final. Virtuelle metoder = polymorfi 7
Hund h Polymorfi: eksempel Rasehund r Hund g void bjeff() { System.out.println("Voff voff"); void bjeff() { System.out.println("Voff voff"); void bjeff() { System.out.println("Vov vov"); Anta: Hva skrives ut ved hvert av kallene: Hund h = new Hund(); Rasehund r = new Rasehund(); Hund g = r; h.bjeff(); r.bjeff(); g.bjeff(); voff-voff vov-vov vov-vov 8 UanseK hva slags peker vi bruker for å komme Ml objektet, så er det den dypest definerte metoden som brukes (men metoden må vær kjent for den pekeren som brukes)
Viktig bruk av polymorfi class Bil { int beregnavgib( ) {... class Personbil extends Bil {int beregnavgib( ) {... class Lastebil extends Bil {int beregnavgib( ) {... class Drosje extends Personbil {int beregnavgib( ) {... tab Bil[ ] tab = new Bil[1000]; <lag biler og la tab peke på disse>; for ( int ind = 0; ind < antall; ind++) { int betal = tab[ind].beregnavgiz( ); <bruk betal>; Hva skjer om class Bil er definert uten metoden beregnavgib? Hva skjer om metoden beregnavgib i class Bil er abstrakt? 9
Bruk av instanceof class Bil { String regnr;... class Personbil extends Bil { int antpass;... class Lastebil extends Bil { double lastevekt;... class Drosje extends Personbil { int LøyveNr;... (prøv å unngå ved å bruke polymorfi) (og lim casing ) HashMap <String, Bil> h; h = new HashMap <String,Bil> ( );... for ( Bil b: h.values ( ) ) { String nr = b.regnr; // eventuelt kall på virtuell metode: b.beregnavgiz( ); if (b instanceof Pesonbil) { Personbil pb = (Personbil) b; int pas = pb.antpass; else { if (b instanceof Lastebil) { Lastebil ls = (Lastebil) b; double lv = ls.lastevekt; 10
interface TilUtlån GrensesniM Verk Dokument interface Antikvarisk Bok CD Video Tidskriftnr UtlånbarBok AntekvUtlånbrCD IkkeLånbarCD Utlånbart Tidsskriftnr IkkeLånbartTids skriftnr AntikvariskBok Utlånbart, Antekvarisk Tidsskrift En klasse kan Ilføres et ubegrenset antall interface er Dvs. en klasse kan spille et ubegrenset antall roller Antikvarisk tidsskriftnr 11
Tre klasser som kan spille mange roller Skatt Bil Miljo Lastebil Personbil LastebilMedSkattogMiljo MiljoBil Men metodene må (dessverre) skrives på nytt hver gang de brukes 12
Et objekt og noen pekere Bil minbil; Lastebil minlast; LastebilMedSkaMogMiljø denne; SkaM skameobjekt; Miljo miljoting; new LastebilMedSkaKogMiljø() regnr lastevekt toll ( ) momssats( ) Object obj; Object Bil Lastebil rollen SkaM Hva kan vi se gjennom de forskjellige pekerene? co2utslipp( ) svanemerket( ) rollen Miljo Det er sant: Vi kan ha pekere av interface-type utslipp innkjopspris egne Ing (og egen rolle) 13
class SortertLenketListeAvBiler { Bil forste; settinn (Bil pek) { int verdi = forste.sammenlign(pek);... Bil taut(...) {... Objekt av class SortertLenketListeAvBiler Motivasjon for generiske typer class Bil { Bil neste; <mer datastruktur> int sammenlign (Bil b) {... Bil forste settinn(bil pek) Bil taut( ) neste sammenlign(bil b) neste sammenlign(bil b) neste sammenlign(bil b) neste sammenlign(bil b)
class SortertGenLenketListe<T> { T forste; settinn (T pek) { int verdi = forste.compareto(pek);... T taut(...) {... En ikke helt riktig skisse av en datastruktur (Vi må gi T en verdi før vi kan lage en liste) settinn(t pek ) T taut( ) T forste T compareto(t p) T compareto(t p) T compareto(t p) T compareto(t p) Men hvordan skal vi vite at T inneholder metoden compareto (T p)?
class SortertGenLenketListe<T extends Comparable <T>> { T forste; settinn (T pek) { T denne; int verdi = forste.compareto(pek);... T taut(...) {... class Bil implements Comparable<Bil> { Bil nestebil; <mer datastruktur> int compareto (Bil b) {... SortertGenLenketListe <Bil> listen = new SortertGenLenketListe <Bil> ( ); Svar: La T implementere Comparable Bil forste nestebil compareto(bil b) nestebil compareto(bil b) nestebil compareto(bil b) settinn(bil pek ) Bil taut( ) nestebil compareto(bil b) interface Comparable <T> { int compareto (T p);
Unntaksbehandling try { <USIKKER KODE> <Hvis det skjer noe galt:> throw new Unntaksklassen( ); Enkleste form for unntaksbehandling. catch (Unntaksklassen unt) { < Unntaksbehandling. DeMe hoppes over når ikke noe unormalt/galt har hendt > < her fortsemer vanligvis programmet både emer normal uoøring og emer behandling av eventuelle unntak > På forhånd har vi deklarert: class Unntaksklassen extends ExcepMon {... 17
A a int b( ) throws Unntaksklassen { try { x = b ( ); Når unntak oppstår i en metode som ikke fanger og behandler unntaket selv catch (Unntaksklassen unt) { < Unntaksbehandling. Hoppes over når intet unormalt har hendt > < her fortsemer programmet både emer normal uoøring og emer behandling av eventuelle unntak > A kaller B try { b oppdager en feil: throw new Unntaksklassen ( ) ;.... finally { <gjøres allid> Normal retur fra b Il a: return 17; throw Starter å kaste et unntak try Står foran en blokk som kan fange et unntak catch Står foran en blokk som behandler et unntak. throws Kaster et unntak videre. Brukes i overskriben på en metode som ikke selv vil behandle et unntak finally gjøres allid, også når throw kaster kalleren ut av metoden 18
import javax.swing.*; import java.awt.*; class Firkant extends JPanel { Firkant() { // angir foretrukket størrelse på dette lerretet. setpreferredsize(new Dimension(200, 200)); public void paintcomponent(graphics g) { // Her tegner vi g.drawrect(50, 50, 100, 100); class FirkantDemo extends JFrame { FirkantDemo() { settitle("firkantdemo"); Container lerret = getcontentpane(); JPanel panel = new Firkant(); lerret.add(panel); // peker til vindusflaten // lag panel (med firkant ) // legg firkanten til vinduet setdefaultcloseoperation(jframe.exit_on_close); pack( ); //passe stort vindu setvisible(true); // gjør alt synlig public static void main(string[] args) { new FirkantDemo(); 19
Hva skjer ved et knappetrykk? knapp Dette objektet synes på skjermen (som en knapp) Hei knappelytter knapp.addactionlistener(knappelytter); forteller kjøresystemet at objektet som knappelytter peker på skal ha beskjed når noe skjer med knappen knapp. Objektet som knappelytter peker på blir satt opp som lytter ( actionlistener ) for knappen knapp. Kobling i kjøre-systemet DeKe objektet lyker på knappen actionperformed( ) Når noen trykker på knappen, kaller kjøresystemet metoden actionperformed i det objektet som er satt opp som lytter for denne knappen.
GUI og hendelser Op sys (Win, Linux,..) DiK Program sin Event Dispatch Thread Hver Ing brukeren gjør (flymer eller klikker musa, trykker på tastaturet...) gjør operaivsystemet om Il en pakke som sendes Il GUI programmet. GUI et uoøres av en tråd som heter Event Dispatch Thread (EDT). EDT behandler alle hendelsene (pakkene), en for en. Hver gang f.eks musa flymes em eneste punkt bortover genereres en ny slik pakke (køen kan forkortes) 21
Maskinarkitektur, f.eks. 4 prosessorer Javas minnemodell prosessor registre cache 1 cache 2 prosessor registre cache 1 System bus Minne (RAM) prosessor registre cache 1 cache 2 prosessor registre cache 1 Bruk volaile for å skrive variable helt Ilbake Il Minne (RAM) 22
Tråder i Java: class MinTråd extends Thread { public void run( ) { while (<mer å gjøre>) { <gjør noe>; try {sleep(<et tall, dvs. en stund>); catch (InterruptedException e) {... // end while // end run //end class MinTråd run inneholder vanligvis en løkke som utføres til oppgaven er ferdig. MinTråd objekt (en tråd) start run tråden En tråd lages og startes opp slik: MinTråd tråden; tråden = new MinTråd( ); tråden.start( ); Her går den nye og den gamle tråden (dette programmet), vider hver for seg start( ) er en metode i Thread som må kalles opp for å få startet tråden. start-metoden vil igjen kalle metoden run (som vi selv programmerer). 23
main JFrame f = new Traffic(); f Her er masse felles datastruktur og metoder for å tegne opp rammen rundt lysene og knappene nederst. actionperformed if (event == newsetbutton) { lights[nlights] = new SetOfLights(area, lightsposition); lights[nlights].start();.... SetOfLights[] lights = new SetOfLights[3]; Traffic3- klasse- datastruktur class SetOfLights er en indre klasse i class Traffic 0 1 2 SetOfLights objekt (en tråd) start run while (true) <tegn lys> Traffic3-objekt SetOfLights objekt (en tråd) start run while (true) <tegn lys> SetOfLights objekt (en tråd) start run while (true) <tegn lys> 24
Kritiske regioner / synkroniserte metoder. Felles data: Tråden Ta: Tråden Gi: int penger = 2000; synchronized void ta (int ant) felles felles.ta(500); felles felles.gi(500); int x; x = penger; x -= ant ; penger = x; synchronized void gi (int ant) int x; x = penger; x += ant ; penger = x; En kritisk region er en kodebit som utføres ferdig før en annen tråd får lov å utføre en kritisk region (med hensyn på de samme dataene). Max en tråd om gangen eier objektet (dataene, monitoren). Metodene i et objekt blir kritiske regioner når det står synchronized foran metodenavnene. Høyst én kritisk region kan utføres inne i et objekt om gangen. Derfor blir den felles datastrukturen inne i objektet beskyttet, og riktig oppdatert (hvis metodene er riktig programmert). Innkapsling 25
Mer om felles data På forrige side lærte dere at felles data (blå felt) vanligvis bare må aksesseres (lese eller skrives i) av en tråd om gangen. Hvis ikke blir det kluss i dataene. Et felles objekt kalles en monitor. Metodene i en monitor har modifikatoren synchronized f.eks. F F put hent Buffer Monitor er ikke noe ord i Java Produsenter Konsumenter 26
wait(); noify(); Kokken må vente når det er to tallerkner i kø Servitøren må vente når det ikke er laget noe mat Kokken må starte opp kelneren igjen når han har laget tallerken nr. 1 (eller allid når han har laget en tallerken?) Servitøren må starte opp kokken igjen når han tar tallerken nr. 2 (eller allid når han tar en tallerken?) wait(); Kokk Servitør wait(); noify(); noify(); 27
Java har én kø for alle wait() instruksjonene på samme objekt! kø for å få låsen første gang ventende tråder produsenter while ( ) { <lag noe>; p.putinn(...); while ( ) { <lag noe>; p.putinn(...); synchronized void putinn( int verdi) while (full) wait(); // nå er bufferet ikke fult < legg inn> // nå er bufferet ikke fullt nomfy(); synchronized int hentut while (empty) wait(); // nå er bufferet ikke tomt <ta ut et element> // nå er bufferet ikke fult nomfy(); return element; konsumenter while ( ) { p.hentut <bruk deme>; while ( ) { p.hentut <bruk deme>; En monitor (et objekt) Pass på: Unngå vranglås (deadlock)
Lock laas = new ReentrantLock(); CondiIon ikkefull = laas.newcondiion(); CondiIon ikketom = laas.newcondiion(); void seminn ( int verdi) throws InterrupedExcepIon laas.lock(); try { while (full) ikkefull.await(); // nå er det helst sikkert ikke fult : // det er lagt inn noe, så det er helt sikkert ikke tomt: ikketom.signal(); finally { laas.unlock(); int taut ( ) throws InterrupedExcepIon laas.lock(); try { while (tom) ikketom.await(); // nå er det helst sikkert ikke tomt; : // det er det tam ut noe, så det er helt sikkert ikke fult: ikkefull.signal(); finally { laas.unlock(); Nå har vi en kø per bemngelse som skal oppfylles Bra!
Barierer i parallellprogrammering CountDownLatch bariere = new CountDownLatch(antallTrader); bariere.await(); Alle trådene sier fra når de er ferdig, dvs. når de har nådd barieren: bariere.countdown(); tid SLUTT
public void run( ) mor <start sortering, event. gjør lim selv>; ventpaalle (); mor.ferdig ( ); synchronized void ventpaalle( )... while (antallbarn!= 0) wait( );.... synchronized void ferdig( ) antallbarn ; nomfy ( ); Quicksort med tråder public void run( ) mor <start sortering, event. gjør lim selv>; ventpaalle (); mor.ferdig ( ); synchronized void ventpaalle( )... while (antallbarn!= 0) wait( );.... synchronized void ferdig( ) antallbarn ; nomfy ( ); public void run( ) mor <start sortering, event. gjør lim selv>; ventpaalle (); mor.ferdig ( ); synchronized void ventpaalle( )... while (antallbarn!= 0) wait( );.... synchronized void ferdig( ) antallbarn ; nomfy ( );