TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Klasser, objekt, metoder, parametrar, konstruktorer, samlingar och tillstånd. En tillbakablick på kapitel 3 i kursboken och projektet clock-display. Illustration av "metodanropskedjor" i projektet auction i kapitel 4. Detta handlar primärt inte om hur man skriver program, utan om hur man bör tänka, när man skriver program!
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl I projektet clock-display har vi två klasser: class ClockDisplay och class NumberDisplay. Vi "beställer" ett nytt clock- displayobjekt clockDis1 från "affären" eller "verkstaden" class ClockDisplay. Vad hände egentligen ??
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Jo, när vi "beställer" clockDis1 från class ClockDisplay anropar vi konstruktorn i den klassen. "Anropet" hade formen: new ClockDisplay() och det skickades till "ordermottagningen" dvs konstruktorn i ClockDisplay : public ClockDisplay() { hours = new NumberDisplay(24); minutes = new NumberDisplay(60); updateDisplay(); } som utförde detta, och levererade resultaten hours och minutes till ClockDisplay. I klassen ClockDisplay fanns deklarationerna private NumberDisplay hours; private NumberDisplay minutes; private String displayString; Det man kan göra nu i " ClockDisplay -verkstaden" är att "be" objekten hours, minutes och displayString utföra sina inbyggda funktioner, dvs de "publika" metoder som fanns i klasserna NumberDisplay resp. String:
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl clockDis1 beställde från "underleverantören" NumberDisplay två st siffervisarenheter: hours och minutes, som var och en kan visa två siffror. Enheten hours är "fabriksinställd" på att automatiskt slå om till 00 när den kommer till 24 och minutes slår automatiskt om till 00 när den kommer till 60. Efter det att " NumberDisplay -verkstaden" har levererat de två enheterna hours och minutes till clockDis1, har inte ClockDisplay någon mer kontakt med sin underleverantör, utan använder bara de funktioner, som redan finns inbyggda i de levererade komponenterna hours och minutes.
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Exempel på sådant som class ClockDisplay ber objekten hours och minutes att utföra: minutes.increment( ); if(minutes.getValue( ) == 0) hours.increment( ); displayString = hours.getDisplayValue( ) + ":" + minutes.getDisplayValue( ); Anm. Den sista satsen, tvåraderssatsen ovan, sätter samman, konkatenerar, "timsiffrorna", som returneras från hours.getDisplayValue( ), tecknet kolon och "minutsiffrorna", som returneras från minutes.getDisplayValue( ), till en enda sträng med fem tecken, t.ex. "10:57". Tecknet + mellan två strängobjekt (eller strängvärden) betyder konkatenering.
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Exempel på sådant som "är inbyggt" i hours och minutes : public String getDisplayValue() { if(value < 10) return "0" + value; else return "" + value; } public void setValue(int replacementValue) { if((replacementValue >= 0) && (replacementValue < limit)) value = replacementValue; } Notera att vi I uttrycken "0" + value och "" + value har en implicit, underförstådd, typomvandling av heltalsvärdet value till "siffra/siffror" dvs till strängvärden.
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: import javax.swing.*; import java.awt.*; /** * The NumberDisplay class represents a digital number display that can hold * values from zero to a given limit. The limit can be specified when creating * the display. The values range from zero (inclusive) to limit-1. If used, * for example, for the seconds on a digital clock, the limit would be 60, * resulting in display values from 0 to 59. When incremented, the display * automatically rolls over to zero when reaching the limit. * Michael Kolling and David J. Barnes * Modified by Bengt */ public class NumberDisplay extends JLabel { private int limit; private int value;
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class NumberDisplay continued /** * Constructor for objects of class NumberDisplay. * Set the limit at which the display rolls over. */ public NumberDisplay(int rollOverLimit) { limit = rollOverLimit; value = 0; } /** * Instance methods: */ public int getValue() { return value; } public void setValue(int replacementValue) { if((replacementValue >= 0) && (replacementValue < limit)) { value = replacementValue; }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class NumberDisplay continued 2. /** * More instance methods */ public String getDisplayValue() { String txt=""; if(value < 10) { txt ="0" + value; } else { txt = "" + value; } return txt; } public void increment() { value = (value + 1) % limit; }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: import java.awt.*; import javax.swing.*; /** * The ClockDisplay class implements a digital clock display for a * European-style 24 hour clock. The clock shows hours, minutes and * seconds..The range of the clock is 00:00 (midnight) to 23:59:59 * (one second before midnight). The clock display receives "ticks" * (via the timeTick method) every second and reacts by incrementing * the display. This is done in the usual clock fashion: the hour * increments when the minutes roll over to zero. Michael Kolling and David J. Barnes * Modifiewd by Bengt */ public class ClockDisplay extends JPanel implements Runnable { public Thread activity = new Thread(this); private Container contentPane; private NumberDisplay hours; private NumberDisplay minutes; private NumberDisplay seconds;
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class ClockDisåplay continued 1. /** * Constructor for ClockDisplay objects. This constructor * creates a new clock set at 00:00. */ public ClockDisplay() { hours = new NumberDisplay(24); minutes = new NumberDisplay(60); seconds = new NumberDisplay(60); hours.setForeground(Color.RED); minutes.setForeground(Color.RED); seconds.setForeground(Color.RED); hours.setBackground(Color.yellow); minutes.setBackground(Color.yellow); seconds.setBackground(Color.yellow); hours.setFont(new Font("Courier", Font.BOLD, 48)); minutes.setFont(new Font("Courier", Font.BOLD, 48)); seconds.setFont(new Font("Courier", Font.BOLD, 48)); JLabel timeString = new JLabel("Time: "); JLabel kolon1 = new JLabel(":"); JLabel kolon2 = new JLabel(":");
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class ClockDisplay continued 2.Constructor definition continued timeString.setFont(new Font("Courier", Font.BOLD, 48)); kolon1.setFont(new Font("Courier", Font.BOLD, 48)); kolon2.setFont(new Font("Courier", Font.BOLD, 48)); hours.setVisible(true); minutes.setVisible(true); seconds.setVisible(true); timeString.setVisible(true); kolon1.setVisible(true); kolon2.setVisible(true); this.setLayout(new GridLayout(1,6)); add(timeString); add(hours); add(kolon1); add(minutes); add(kolon2); add(seconds); updateDisplay(); setVisible(true); activity.start(); }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class ClockDisplay continued 3 /** * Detta trådobjekt körs parallelt med andra trådar. */ public void run() { while(!Thread.interrupted()) { try { Thread.sleep(1000); } catch(InterruptedException e){break;} timeTick(); String hoursString = hours.getDisplayValue(); String minutesString = minutes.getDisplayValue(); String secondsString = seconds.getDisplayValue(); System.out.println(hoursString + ":" + minutesString + ":" + secondsString); }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class ClockDisplay continued 4 /** * This method should get called once every minute - it makes * the clock display go one minute forward. */ public void timeTick() { seconds.increment(); if(seconds.getValue() == 0) { // it just rolled over! minutes.increment(); if(minutes.getValue() == 0) { // it just … hours.increment(); } updateDisplay(); }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // Class ClockDisplay continued 5 /** * Set the time of the display to the specified hour and minute. */ public void setTime(int hour, int minute, int second) { hours.setValue(hour); minutes.setValue(minute); seconds.setValue(second); updateDisplay(); } /** * Update the string that represents the display. */ public void updateDisplay() { hours.setText(hours.getDisplayValue()); minutes.setText(minutes.getDisplayValue()); seconds.setText(seconds.getDisplayValue()); }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: import java.awt.*; import javax.swing.*; /** * class Digitalklocka ärver en mängd funktionalitet från klassen JFrame i * biblioteket javax.swing. JFrame i sin tur ärver en stor del av sin * funktionalitet från: Component, Container, Window, och Frame * Här visas i detta JFrame JPanels och JLabels. Grundfunktioner * hämtade från Kapitel 3: NumeberDispaly och ClockDisplay Bengt Lennartsson */ public class Digitalklocka extends JFrame{ // instance variables - replace the example below with your own private ClockDisplay klockan; private Container contentPane;
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: //class Digitalklocka, continued 1 // Constructor for objects of class FL_04_c public Digitalklocka( ) { this.setTitle("Digitalklocka"); this.setSize(500, 300); klockan = new ClockDisplay(); contentPane = this.getContentPane(); contentPane.add(klockan); this.pack(); this.setVisible(true); } // Klassmetoder: public static void stopAllObjects() { System.exit(0); }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: // class Digitalklocka continued 2 // Instansmetoder: public void stopThisObject() { this.klockan.activity.interrupt(); this.dispose(); } public void setClock(int tim, int min, int sek) { klockan.setTime(tim, min, sek); } /** När programmet körs utan användning av BlueJ * public static void main(String [] args) { * new Digitalklocka(); * } */ }
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: Digitalklockan som ett JFrame objekt, som innehåller ett JPanel objekt som i sin tur innehåller sex JLabel objekt:
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl En lätt "upphottad" digitalklocka: Vi går tillbaka till: public class ClockDisplay extends JPanel implements Runnable { public Thread activity = new Thread(this); Man skulle vilja att objekt som skapas från klassen ClockDisplay hade förmåga att bete sig båda som JPanelobjekt och som Threadobjekt. I java är inte multipel ärvning tillåten, dvs vi får inte skriva: public class ClockDisplay extends JPanel extends Runnable { Däremot kan vi låta ClockDisplay ärva från en klass, JPanel, så att ClockDispaly objekt kan det som JPanel objekt kan. Sedan skapar vi ett annat objekt activity som är ett Tread objekt och vi skickar med en referens, this, till vårt JPanel / ClockDisplay objekt, när vi ber klassen Thread s konstruktor skapa objektet activity. Därmed får tidshanteringen i Thread en referens till vårt objekt så att Thread kan väcka detta, när det sovit en sekund.
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Vi tar nu en titt på projektet auction i kapitel 4. Pilarna i klassdia- grammet visar att klassen Auction känner till begreppen Lot, Bid och Person, men när man tittar på koden för class Auction, ser man, att enda sättet att därifrån komma åt några sådana objekt, är via ArrayList -objektet lots.
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Lot- objekt Bid- objekt Person- objekt lots nextLotNumber n-1 ArrayList-objekt String- objekt highestBid description number String- objekt highestBid description number name bidder value "Anna" "cykel" 19 n name "Johan" highestBid description number 1 bidder value "soffa"
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl BlueJ-projektet Auction: Via ArrayList -objektet lots kan man i klassen Auction komma åt de Lot -objekt, som man lagt in i systemet med metoden enterLot(String desc). "Kommer man åt" ett Lot -objekt, dvs har man fått tillgång till en referens till det, kan man sedan använda metoderna public String getDescription() public int getNumber() public Bid getHighestBid() i class Lot, för att få tillgång till beskrivningsträngen, numret, resp. det budobjekt som representerar högsta budet på detta Lot -objekt. Man kan också be Lot -objekt att få metoderna public String toString() public boolean bidFor(Bid bid) utförda. Se övningsexempel på nästa bild,
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl BlueJ-projektet Auction: Om man i klassen Auction vill skriva ut namnet på den budgivare (om det finns någon), som givit ett bud på lot-objekt nr 19, hur gör man då? Ledtråd: Man börjar med att tänka!
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Om tolkning av metodanropskedjor: Om man någonstans i ett (java-)program har en kodrad enligt: a.b().c().d().e(x, y); hur bär man sig åt för att få fram vad den betyder?
TNSL04 – IT grundkurs. VT2008. Föreläsning nr 4, torsdag 28 feb. kl Om tolkning av metodanropskedjor: En metodanropskedja enligt a.b().c().d().e(x, y); måste tolkas från vänster till höger. Man ber objektet a utföra metoden b, och man kan inte veta vad metoden b innebär, förrän man listat ut från vilken klass objektet a är skapat. Detta listar man ut genom att titta på deklarationen av objektet a (normalt i början av klassen eller möjligen metoden där den aktuella programraden finns). Deklarationen har i princip formen: private AKlassen a... och den säger då att namnet på klassen som skapat objektet a är det namn som står på den plats ordet AKlassen ovan står. Man får då gå till koden för den klassen och leta upp metoden med namnet b. Man tittar efter vilken typ av objekt metoden b returnerar, dvs namnet på den klass som skapar returobjektet, och i denna klass letar man upp metoden med namnet c osv. Det finns inget annat sätt än att tolka från vänster till höger. Att en metod t.ex. har namnet e säger ingenting om vad den gör, om jag inte vet i vilken klass just den aktuella metoden är definierad.