Programmering hh.se/db2004 Föreläsning 11: Objektorienterad programmering - att definiera datatyper Verónica Gaspes www2.hh.se/staff/vero www2.hh.se/staff/vero/programmering Datatyper Hittills Vi har lärt oss att använda datatyper i våra program. Vi använder primitiva typer och referenstyper. Primitiva typer char int long double Idag Program där man skapar egna datatyper! Referenstyper type[] String java.awt.color från Java Picture från kursboken Center for Research on Embedded Systems IDE-sektionen 1 / 1 2 / 1 Att definiera datatyper i Java Laddade partiklar För att definiera en datatyp 1 Beskriv värdemängden. 2 Beskriv operationerna för dessa värden. En Javaklass Definierar en datatyp genom att använda 1 Instansvariabler (för värdemängden) 2 Metoder (för operationerna med dessa värden) 3 Konstruerare (för att skapa och initiera nya objekt) 3 / 1 Mål En datatyp för laddade partiklar. Värdemängd Tre reella tal: position x och y samt elektriskt laddning. (x,y) r q (Rx,Ry) Operationer 1 Skapa en ny partikel vid (rx, ry ) med elektrisk laddning q. 2 Bestäm fältets styrka (potentialen) V vid en viss punkt (x, y) orsakad av en partikel. (V = k q r ) 3 Konvertera till String 4 / 1
En datatyp för laddade partiklar API public class Charge datatyp för laddade partiklar Charge(double x0,double y0,double q0) double potentialat(double x, double y) elektrisk potential vid (x,y) orsakad av laddningen String tostring() strängrepresentation 5 / 1 En datatyp för laddade partiklar Ett enkelt klientprogram Använder datatypens operationer för att beräkna något: public static void main(string[] cmdln){ double x = Double.parseDouble(cmdLn[0]); double y = Double.parseDouble(cmdLn[1]); Charge c1 = new Charge(.51,.63, 21.3); Charge c2 = new Charge(.13,.94, 81.9); double v1 = c1.potentialat(x, y); double v2 = c2.potentialat(x, y); System.out.println(c1); System.out.println(c2); System.out.println(v1 + v2); Metoden tostring() anropas automatiskt av println! 6 / 1 En datatyp för laddade partiklar Implementation - instansvariabler private final double rx, ry; private final double q;. Instansvariabler 1 Beskriver mängden värden som bildar typen. 2 Deklareras utanför metoderna. 3 Använd (nästan) alltid private. 4 Använd final med instansvariabler som inte ändras. 7 / 1 En datatyp för laddade partiklar Implementation - konstruerare Beskriver vad som händer när man skapar ett objekt: public Charge(double x0,double y0,double q0){ rx = x0; ry = y0; q = q0; Konstrueraren 1 Tilldelar värden till instansvariablerna. 2 Har ingen returtyp. 3 Heter som klassen. 8 / 1
En datatyp för laddade partiklar En datatyp klassens anatomi Implementation - metoder Metoderna implementerar operationerna public double potentialat(double x, double y){ double dx = x-rx; double dy = y-ry; double r = Math.sqrt(dx*dx + dy*dy); double k = 8.99e09; return k*q/r; Metoderna Arbetar på instansvariablerna: metoden är inte static! 9 / 1 private final double rx, ry; private final double q; public Charge(double x0,double y0,double q0){ rx = x0; ry = y0; q = q0; public double potentialat(double x, double y){ double dx = x-rx; double dy = y-ry; double r = Math.sqrt(dx*dx + dy*dy); double k = 8.99e09; return k*q/r; public String tostring(){ return q + " at (" + rx + ", " + ry + ")"; 10 / 1 Ett till exempel med laddade partiklar Att lösa Hur ser fältet ut? Man kan tänka sig att visualisera laddningsfältet då flera partiklar finns utspridda. Fältets värde Vid en viss punkt är fältets värde summan av alla partiklars potentialer vid den punkten. En färg Vi kan använda fältets värde för att bestämma en färg för den punkten. Till exempel, en nyans av röd, där nyansen ges av fältets värde! Hur relaterar vi pixlar till (x,y)-koordinaterna? Säg att vi använder SIZExSIZE pixlar för kvadraten 1x1. Vilka (x, y) har vi i pixeln (i,j)? (i/size, j/size) men som doubles! Hur gör vi om fältets värde till en färg? Om vi lyckas få ett tal mellan 0 och 255 kan vi använda detta för röd och komplementet för blå! 11 / 1 12 / 1
Lite kodfragment Indata // read in N point charges int N = StdIn.readInt(); Charge[] a = new Charge[N]; for (int k = 0; k < N; k++) { double x0 = StdIn.readDouble(); double y0 = StdIn.readDouble(); double q0 = StdIn.readDouble(); a[k] = new Charge(x0, y0, q0); Observera Fält av laddade partiklar! Mera kodfragment Räkna upp fältet Picture pic = new Picture(SIZE, SIZE); for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { double V = 0.0; for (int k = 0; k < N; k++) { double x = 1.0 * i / SIZE; double y = 1.0 * j / SIZE; V = V + a[k].potentialat(x, y); Color c = getcolor(v); pic.set(i, SIZE-1-j, c); pic.show(); Vi använder 1.0*i för att göra om till double, istället för (double)i 13 / 1 14 / 1 Sista kodfragmentet Metoden getcolor private static Color getcolor(double potential){ double t = 128 + potential / 2.0e10; int red = 0; if (t < 0) red = 0; else if (t > 255) red = 255; else red = (int) t; return new Color(red, 0, 255-red); Räkneexempel Laddningar var ett exempel av oföränderliga objekt. Som vi redan har sett kan det också behövas föränderliga objekt. Vi studerar räknare. En räknare När den kommer ut från fabriken har den 1 en knapp för att nollställa, 2 en knapp för att räkna upp, 3 en display att avläsa värdet i. 15 / 1 16 / 1
Räkneexempel Räknaren i Java Vad är en räknare? Ett heltal! Vi använder detta för att utforma instansvariablerna! Vilka operationer vill vi göra? 1 En metod för att nollställa 2 En metod för att räkna upp 3 En metod för att avläsa Dessa metoder måste förändra värdet på instanvariablen! Klassen public class Counter{ private int value; public Counter(){value = 0; public void inc(){value++; public void reset(){value = 0; public int getvalue(){return value; Konstrueraren? Tilldelar startvärde till instansvariabeln! 17 / 1 public String tostring(){ return ""+value; 18 / 1 Vem vill ha en räknare? Varför skall man ha en räknare i ett program och inte bara ett heltal? En fråga om design Med heltalen kan man göra mycket annat än att räkna upp och sätta till 0. Med en heltalsvariabel i programmet kan man av mistag använda den till annat! Det är lättare hänt än man tror! En fråga om trådar Det finns program med flera main som samarbetar. Till exempel en webserver startar en tråd för varje klient. Om flera trådar vill samarbeta måste det delade objektet samordnas, och det är bättre att göra det med ett objekt än med en variabel. Några ord om design Datatyp En mängd värden och operationer på dessa värden. Inkapsling Göm typens representationen! Dela upp ansvaret! 1 En klass erbjuder representationen och koden för operationerna 2 Klienter använder klassen som en svart låda 3 APIn beskriver ett kontrakt mellan klienten och klassen. Man behöver inte veta hur datatypen är implementerad för att kunna använda den! 19 / 1 20 / 1
Intuition Intuition Klienten Måste kunna använda APIn! API 1 Volym 2 byta kanal 3... Implementationen Katodstrålrör... Klienten Måste kunna använda APIn! API 1 Volym 2 byta kanal 3... Implementationen Plasmaskärm... Klienten och implementationen måste vara överens om APIn! Man kan byta till en bättre implementation utan att behöva ändra klienten! 21 / 1 22 / 1 Räknaren igen Inkapsling Om vi gör public class Counter{ public int value; public Counter()value = 0; Låter vi klienter göra Counter algoreinflorida = new Counter(); algoreinflorida.value = 16022; Vi kapslar in representationen public class Counter{ private int value; public Counter()value = 0; Då ger Counter algoreinflorida = new Counter(); algoreinflorida.value = 16022; Och voops Al Gore får 16022 röster i Florida! kompileringsfel! 23 / 1 24 / 1