INF1010 oversikt med Subklasser mm Unntaksbehandling GUI Tråder 19. mai 2011 Stein Gjessing InsBtuC for informabkk Universitetet i Oslo
Hvordan starte å løse et problem Eksempel: Bank I et mini-system for en bank skal alle konti registreres med innestående beløp og hvilken kunde som eier kontoen. Hver kunde registreres med navn og telefonnummer (åtte siffer). Det skal være mulig for kunder å ta ut og sette inn beløp. En bruker skal kommunisere med systemet via et brukergrensesnitt. Substantivmetoden! 2
Model- View- Control main navn: bnk type: BankKontroll bnk = new BankKontroll(); bnk.ordreløkke(); BankKontroll- klassedatastruktur BankUtsyn- objekt leskommando beomnavnogbelop hentnavn hentbelop beomoghentnavn skrivsum BankKontroll navn: b type: Bank BankKontroll- objekt Bank- objekt lagnykunde lagbankkunde OernBankKunde OernBankKunde secinn sumallekonb sumallekonb secinn ordrelokke navn: konb navn: u type: HashMap type: BankUtsyn Konto- objekter HashMap- objekt 3
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 4
Konvertering av pekere class- cast MasterStudent master = new MasterStudent(); Person Konvertering oppover: Student stud = master; Person pers = master; Person pers Student MasterStudent Konvertering nedover: (Student) pers Student stud (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 ) 5
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 eksplisic, 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(); 6
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 (erstace) 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! 8
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 9 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 beregnavgia( ) {... class Personbil extends Bil {int beregnavgia( ) {... class Lastebil extends Bil {int beregnavgia( ) {... class Drosje extends Personbil {int beregnavgia( ) {... tab Bil[ ] tab = new Bil[1000]; <lag biler og la tab peke på disse>; for ( Bil b: tab) { int betal = b.beregnavgiy( ); <bruk betal>; Hva skjer om class Bil er definert uten metoden beregnavgia? Hva skjer om metoden beregnavgia i class Bil er abstrakt? 10
Bruk av instanceof (prøv å unngå ved å bruke polymorfi) class Bil { String regnr;... class Personbil extends Bil { int antpass;... class Lastebil extends Bil { double lastevekt;... class Drosje extends Personbil { int LøyveNr;... (og lic casbng ) HashMap <String, Bil> h; h = new HashMap <String,Bil> ( );... for ( Bil b: h.values ( ) ) { String nr = b.regnr; // eventuelt kall på virtuell metode: b.beregnavgiy( ); 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; 11
interface TilUtlån GrensesniC 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 n En klasse kan Blføres et ubegrenset antall interface- er n Dvs. en klasse kan spille et ubegrenset antall roller Antikvarisk tidsskriftnr 12
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" 13
Roller Bil minbil; Lastebil minlast; LastebilMedSkaCogMiljø denne; SkaC skaceobjekt; Miljo miljoting; new LastebilMedSkaKogMiljø() regnr lastevekt toll ( ) momssats( ) Object obj; Object Bil Laste- bil rollen SkaC 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 Bng (og egen rolle) 14
class SortertLenketListeAvBiler { Element forste; settinn (Bil pek) { int verdi = forste.denne.sammenlign(pek);... Bil taut(...) {... Motivasjon for generiske typer class Bil { <mer datastruktur> int sammenlign (Bil b) {... Element forste settinn(bil pek) Bil taut( ) neste sammenlign(bil b) neste sammenlign(bil b) neste sammenlign(bil b) Objekt av class SortertLenketListeAvBiler sammenlign(bil b) class Element { Element neste; Bil denne;
class SortertGenLenketListe<T> { Element forste; settinn (T pek) { int verdi = forste.denne. compareto(pek);... T taut(...) {... Men hvordan skal vi vite at T inneholder metoden compareto (T b)? En ikke helt riktig skisse av en datastruktur (Vi må gi T en verdi før vi kan lage en liste) Element forste settinn(t pek) T taut( ) neste neste neste denne T denne T denne T compareto(t b) compareto(t b) compareto(t b) Objekt av class SortertLenketListeAvBiler compareto(t b) class Element { Element neste; T denne;
class SortertGenLenketListe<T extends Comparable <T>> { Element forste; settinn (T pek) { T denne; int verdi = forste.denne.compareto(pek);... T taut(...) {... Svar: La T implementere Comparable class Bil implements Comparable<Bil> { <mer datastruktur> int compareto (Bil b) {... SortertGenLenketListe <Bil> listen = new SortertGenLenketListe <Bil> ( ); Element forste settinn(t pek) T taut( ) neste compareto(t b) neste compareto(t b) neste denne T denne T denne T compareto(t b) Objekt av class SortertLenketListeAvBiler compareto(t b) interface Comparable <T> { int compareto (T b);
Unntaksbehandling try { <USIKKER KODE> <Hvis det skjer noe galt:> throw new Unntaksklassen( ); Enkleste form for unntaksbehandling. catch (Unntaksklassen unt) { < Unntaksbehandling. DeCe hoppes over når ikke noe unormalt/galt har hendt > < her fortsecer vanligvis programmet både ecer normal uoøring og ecer behandling av eventuelle unntak > På forhånd har vi deklarert: class Unntaksklassen extends ExcepMon {... 18
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 fortsecer programmet både ecer normal uoøring og ecer behandling av eventuelle unntak > A kaller B try { b oppdager en feil: throw new Unntaksklassen ( ) ;.... finally { <gjøres allbd> Normal retur fra b Bl 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 overskriaen på en metode som ikke selv vil behandle et unntak finally - gjøres allbd, også når throw kaster kalleren ut av metoden 19
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(); 20
Hva skjer ved et knappetrykk? Dette objektet synes på skjermen (som en knapp) Hei knapp.addactionlistener(knappelytter); forteller kjøresystemet at objektet som knappelytter peker på skal ha beskjed når noe skjer med knappen knapp. knapp knappelytter Kobling i kjøre-systemet Pekerens type: ActionListener DeKe objektet lyker på knappen actionperformed( ) implementerer grensesnittet ActionListener 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 Bng brukeren gjør (flycer eller klikker musa, trykker på tastaturet...) gjør operabvsystemet om Bl en pakke som sendes Bl 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 flyces ec eneste punkt bortover genereres en ny slik pakke (køen kan forkortes) 22
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 volable for å skrive variable helt Blbake Bl Minne (RAM) 23
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). 24
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> 25
Kritiske regioner / synkroniserte metoder / skjule implementasjon. 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 26
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 27
wait(); nobfy(); Anta at det er plass Bl 3 tallerkener på bordet: Kokken må vente når det er tre tallerkner på bordet 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 allbd når han har laget en tallerken?) Servitøren må starte opp kokken igjen når han tar tallerken nr. 3 (eller allbd når han tar en tallerken?) wait(); Kokk Servitør wait(); nobfy(); nobfy(); 28
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 dece>; while ( ) { p.hentut <bruk dece>; En monitor (et objekt) Pass på: Unngå vranglås (deadlock)
public void run( ) mor <start sortering, event. gjør lic 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 lic 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 lic selv>; ventpaalle (); mor.ferdig ( ); synchronized void ventpaalle( )... while (antallbarn!= 0) wait( );.... synchronized void ferdig( ) antallbarn - - ; nomfy ( );
Lock laas = new ReentrantLock(); CondiBon ikkefull = laas.newcondibon(); CondiBon ikketom = laas.newcondibon(); void secinn ( int verdi) throws InterrupedExcepBon 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 InterrupedExcepBon laas.lock(); try { while (tom) ikketom.await(); // nå er det helst sikkert ikke tomt; : // det er det tac 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