orienterad programmering Föreläsning 3 Exempel: Telefonboken Fält som funktionsresultat Exempel Definiera static double[] vectorsum(double[] a, double[] b) Betrakta sedan följande kodavsnitt:... double[] v1 = new double[100]; double[] v2 = new double[100];... kod som fyller v1 och v2... double[] w = new double[100]; w = LinearAlgebra.vectorSum(v1,v2); Rita en bild av minnesförbrukningen då denna kod exekveras. Mer om fält: att uppdatera ett parameterfält Vad skrivs ut när programmet körs? public class Reset { Kontrast: Parametrar av primitiv typ Vad skrivs ut när programmet körs? public class Swap { public static void reset(int[] a) { for (int i=0; i< a.length; i++) a[i] = 0; public static void main(string[] args) { int[] x = {3, 7, 3, 6; reset(x); for (int i=0; i<x.length; i++) System.out.print(x[i] + ", "); System.out.println(); public static void swap(int x, int y) { int tmp = x; x = y; y = tmp; public static void main(string[] args) { int a = 5; int b = 3; swap(a,b); System.out.println("a=" + a + ", b=" + b);
Fält är objekt Ett fält är ett objekt. i Java karakteriseras av att variabler av objekttyp innehåller en referens (eller pekare) till objektet, och inte objektet själv. Värden av primitiva typer är inte objekt; variabler innehåller själva värdet. En variabel av referenstyp kan innehålla det speciella värdet null. Ett objekt som ingen variabel längre pekar på återvinns av skräpsamlaren. Andra objekt Den viktigaste användningen av klasser är inte som funktionsbibliotek, utan som mallar att skapa objekt från. Klasser som mallar; ett första exempel public class Vector2 { private double x; private double y; public Vector2(double x0, double y0) { x = x0; y = y0; public double getx() {return x; public double gety() {return y; public double length() { return Math.sqrt(x*x + y*y); Klasser som mallar; att skapa objekt Anatomin hos en klass som mall Vi kan skapa objekt av typen Vector2: Vector2 v1 = new Vector2(3,5); Vector2 v2 = new Vector2(-1.5,7); double v1length = v1.length(); Varje objekt har sina egna x och y. Värdena på x och y ges i konstrueraren. Metoderna length, getx och gety hör till objektet, inte till klassen (de är inte static). v1 v2 3 5 1.5 7
Strängar är objekt Paketet java.lang String är en klass i paketet java.lang. Klasser i detta paket är tillgängliga utan import. Här finns förutom String också bl a Integer, Math och System. Klassen String String s = "string example"; skapar ett nytt objekt av klassen String; s innehåller en referens till detta objekt. Exempel på metoder: Anrop Resultat s.length() 14 s.charat(8) x s.substring(7,11) "exam" s.endswith("ring") false Standard input och output Varje Java-program har tillgång till följande objekt: System.out, av klassen PrintStream. Här finns bland annat metoderna print och println. System.in, av klassen InputStream. Denna är inte lämpad för direkt användning; normalt skapar man en Scanner för att läsa indata. För C-programmerare: printf Klassen PrintStream innehåller också metoden printf. (överkurs) printf tar som argument först en formatsträng och sedan ett godtyckligt antal argument som ska skrivas ut. Kan användas för bättre kontroll över formattering, t ex i tabeller. Exempel: System.out.printf("%6d %8.4f\n",i,hSum(i)); Klassen java.util.scanner Exempel på användning av Scanner kan skapas på olika sätt Syfte Från en InputStream: Scanner in = new Scanner(System.in); Från en fil: Scanner in = new Scanner(new File "data.txt"); Från en sträng: Scanner in = new Scanner("1.57 3.2356-1.2"); Enklaste användning: Indata delas upp i ord åtskilda av blanktecken och radbyten. Man kan testa om fler ord finns, om nästa ord kan ses som int, double, osv och i så fall läsa och konvertera ordet. import java.util.scanner; public class Statistics { public static double average(scanner in) { double sum = 0; int count = 0; while (in.hasnextdouble()) { sum = sum + in.nextdouble(); count++; return sum/count;
En användning av Statistics import java.util.scanner; public class StatisticsClient { public static void main(string[] args) { Scanner in = new Scanner(System.in); double avg = Statistics.average(in); System.out.println("Medelvärdet är " + avg); Två sätt att köra programmet java StatisticsClient Användaren skriver in talen; avsluta med Ctrl-D. java StatisticsClient < data.txt Programmet läser tal från filen data.txt. Telefonboken Exempel: Telefonboken Uppgiften Vi ska skriva ett program som kan användas på följande sätt: lect3code> java Main > put kalle 123456 > put lisa 654321 > get kalle Number is 123456 > get eva eva not found > put kalle 111111 > get kalle Number is 111111 > quit Observera Programmet är värdelöst: Vi sparar inte data när programmet avslutas, så nästa gång vi kör programmet måste vi skriva in alla kontakter igen. Vi fixar detta i föreläsning 9. Design Hur kan vi representera telefonboken i vårt program? Detta är en bättre fråga än att börja med att fundera på hur main ska skrivas. Telefonboken Programmets uppbyggnad Två klasser Vi bygger upp programmet av två klasser: Entry och PhoneBookProg. Klassen Entry Instanser av Entry innehåller två strängar, ett namn och ett telefonnummer. Förutom konstrueraren finns två metoder: public String getname() public String getnumber() Klassen PhoneBookProg Här finns main-rutinen, som deklarerar ett fält Entry[] book; där alla data lagras, samt en loop som om och om igen läser ett kommando samt utför detta. Vi definierar här också en hjälprutin prompt. Nästa gång ska vi göra om programmet så det får en bättre struktur. Likhetstest För primitiva typer Man testar på likhet med operatorn ==: int n;... if (n==0) handlezerocase(); else handlenonzerocase(); För heltal, tecken och booleska värden fungerar detta som man förväntar sig; för double kan avrundningsfel ställa till det. För referenstyper Test med == betyder här att testa om två variabler pekar på samma objekt. Normalt ska man i stället använda metoden equals: String cmd;... if (cmd.equals("quit")) System.exit(0); För egna klassser måste man definiera metoden equals.
Klassen Song, början Att använda färdiga klasser public class Song { private byte[] data; private int next; public Song(int duration) { data = new byte[2*duration* SoundDevice.SAMPLING_RATE]; next = 0; public void play(sounddevice device) { SourceDataLine line = device.getline(); line.write(data, 0, next); line.drain(); I labb 2 används klasserna Song och SoundDevice. Ni laddar ner dem och kan titta på dem men det är viktigt att lära sig att kunna använda klasser som man inte vet hur de är uppbyggda genom att studera deras API (Application Programmer s Interface). Vi tittar på API erna för dessa två klasser. Ni ska senare lära er hur man genererar API-dokumentation för klasser som ni själva skriver. Klassen SoundDevice, del av import javax.sound.sampled.*; public class SoundDevice { public static final int SAMPLING_RATE = 44100; private SourceDataLine line; private AudioFormat format = new AudioFormat(SAMPLING_RATE, 16, 1, true, false); Paket Standardbibliotekets klasser är indelade i paket. Klassen AudioFormat ingår i paketet javax.sound.sampled Använder vi denna klass måste vi först i vår fil skriva import javax.sound.sampled.audioformat; Utan detta hittar inte kompilatorn klassen. Använder man flera klasser från paketet kan man i stället skriva import javax.sound.sampled.*;... delar överhoppas... AudioFormat getformat() {return format;
Konstanter Härnäst I SoundDevice fanns också deklarationen public static final int SAMPLING_RATE = 44100; Deklarationer som är public static final används för att definiera konstanter. Det är bättre att införa och använda namnet SAMPLING_RATE än att skriva 44100 på flera ställen i koden. Namn på konstanter skrivs konventionellt med versaler (stora bokstäver). Olika typer av variabler Lokala variabler i funktioner/subrutiner/metoder. Tillståndsvariabler i objekt (x och y i Vector2). Konstanter ( public static final ). Gör färdig labb 2 Ska redovisas senast vid labbtiden på onsdag. Gör övningar På torsdagens övning jobbar vi med funktioner som använder fält. Tänk på objekt Titta på dagens exempel, ladda ner dem och experimentera!