Post on 07-Jul-2020
jonas.kvarnstrom@liu.se – 2015
TDDD78Viktiga begrepp
i programmering / objektorientering
3
jonk
v@id
ajo
nkv@
ida
3
Programkod Minnevid körning
Repetition En variabel består av: Ett symboliskt namn
i programkoden En lagringsplats i minnet,
som kan innehållavariabelns värde
▪ Python:längd = 10höjd = 5hälsning = "hello"färger = [red, green]
10längd
5höjd
"Hello"hälsning
[red, green]färger
4
jonk
v@id
ajo
nkv@
ida
4
Programkod Minnevid körning
Minnesadresser
10int: längd
5int: höjd
"Hello"String: hälsning
[red, green]List: färger
Varje värde "startar" på en specifik minnesaddress Minnesadresser hanteras
"bakom kulisserna" "int längd = 10;"
"lagra 32-bitars heltal 10på adress 10000–10003"
10000–…
10004–…
40000–…
50000–…
5
jonk
v@id
ajo
nkv@
ida
5
Programkod Minnevid körning
Minnesadresser 2
10
5
I vissa språk kan man få vetaminnesadresserna C:
höjd == 5&höjd == 10004("adressen till höjd")
10000–…
10004–…
int: längd
int: höjd
6
jonk
v@id
ajo
nkv@
ida
6
Programkod Minnevid körning
Pekare (1)
10
5
10004int*: höjdpekare
En variabel av pekartypkan innehålla en adress C: "pekare till int" heter "int*" int* höjdpekare = &höjd; Värdet blir adressen 10004
Värdet 10004 är adressentill ett annat värde i minnet
10000–…
10004–…
40000–…
int: längd
int: höjd
7
jonk
v@id
ajo
nkv@
ida
7
Programkod Minnevid körning
Pekare (2): Tilldelning
10
5
10000
Ändra pekarens värdeändra vart den pekar C:
int* höjdpekare = &höjd;höjdpekare = &längd;
10000–…
10004–…
40000–…int*: höjdpekare
int: längd
int: höjd
8
jonk
v@id
ajo
nkv@
ida
8
Programkod Minnevid körning
Pekare (3): Ändra i utpekat värde
10
5 14
10004
För att ändra i värdetpå den utpekade adressenkrävs alltså annan syntax C:
int* höjdpekare = &höjd;*höjdpekare = 14;
10000–…
10004–…
40000–…int*: höjdpekare
int: längd
int: höjd
"*höjdpekare = 14" definieras som"läs pekarens värde (10004),
lagra 14 på den adressen"
10
jonk
v@id
ajo
nkv@
ida
10
Namn Värde i minnet
Pekare i Java
49152Circle: myCircle
I Java är en objektvariabelalltid en pekare! Circle myCircle =
new Circle(10, 20, 30);
10000–…
49152–…
myCircle är pekaren (4/8 bytes),inte objektet!
Object header:
yx
20
(data)
10
r 30
1. Skapa objektet(minne, konstruktor, …)
2. Skapa variabeln,låt den peka på obj.
Java gömmer dess numeriska värde(irrelevant för vår kod):
Vi kan inte få fram talet 49152
11
jonk
v@id
ajo
nkv@
ida
11
Namn Värde i minnet
Pekare i Java (2): Exempel
10000Circle: c1
Två cirklar: Circle c1 = new Circle(1,1,1);
Circle c2 = new Circle(2,2,2);5000–…
10000–…Object header:
yx
1
(data)
1
r 1
20000Circle: c2 11000–…
20000–…Object header:
yx
2
(data)
2
r 2
12
jonk
v@id
ajo
nkv@
ida
12
Namn Värde i minnet
Pekare i Java (3): Tilldelning
10000Circle: c1
c2 = c1; c1, c2 är pekare Tilldela c2 värdet av c1
sätt c2 till 10000 ändra vart c2 pekar
Kommer inte att kopierasjälva cirkeln, fält för fält!
5000–…
10000–…Object header:
yx
1
(data)
1
r 1
10000Circle: c2 11000–…
20000–…Object header:
yx
2
(data)
2
r 2
Kvarvarande objektsom ingen pekar på –inte ett problem i Java
(skräpsamling)
13
jonk
v@id
ajo
nkv@
ida
13
Namn Värde i minnet
Pekare i Java (4): Ändra i utpekat värde
49152Circle: myCircle
Kan ändra i värdet (objektet)som lagras på utpekad adress Ändrar aldrig hela objektet,
alltid en medlem i taget Java: objekt punkt medlem…
myCircle.x = 4711;10000–…
49152–…Object header:
yx
20
(data)
4711
r 30
myCircle.xx-värdet i det objekt
som pekas ut av myCircle
14
jonk
v@id
ajo
nkv@
ida
14
Namn Värde i minnet
Pekare i Java (5): Tilldelning
10000Circle: c1
c2.x = 100; Nu är c1.x också 100!
5000–…
10000–…Object header:
yx
1
(data)
100
r 1
10000Circle: c2 11000–…
15
jonk
v@id
ajo
nkv@
ida
15Exempel: Trädstruktur Trädstruktur:
Alla noder ska veta vem föräldern är Kan inte innehålla föräldern – men kan ha en pekare till den!
▪ class TreeNode {String name; // Pekare till en strängTreeNode parent; // Pekare till en föräldernod…
}
Nod 1
Nod 2 Nod 3 Nod 4 Nod 5
16
jonk
v@id
ajo
nkv@
ida
16Exempel: Trädstruktur (2)
Minne
name: Nod 1
name: Nod 2
parent: 10000
49152–…
10000–…
name: Nod 3
parent: 10000
53284–…
Nod 1
Nod 2 Nod 3
Med pekare:Många kan peka på samma föräldernod
trots att noden bara lagras en gång
17
jonk
v@id
ajo
nkv@
ida
17Exempel: Trädstruktur (3) Men nod 1 har ju ingen förälder! Vad ska parent ha för värde?
Minne
name: Nod 1
parent: ???
name: Nod 2
parent: 10000
49152–…
10000–…
name: Nod 3
parent: 10000
53284–…
18
jonk
v@id
ajo
nkv@
ida
18Null-pekare Alla objektpekare kan ha specialvärdet null Pekar "ingenstans"
▪ "inte applicerbart": Noden har ingen förälder▪ "vi vet inte än"▪ …
Representeras ofta internt som adressen 0▪ Spelar ingen roll för oss▪ I Java ser vi bara värdet null
Minne
name: Nod 1
parent: null
name: Nod 2
parent: 10000
49152–…
10000–…
name: Nod 3
parent: 10000
53284–…
Med pekare:Kan lätt ange avsaknad av värde
19
jonk
v@id
ajo
nkv@
ida
19Null-pekare Vad kan man göra om pekarens värde är null?
Använda själva pekarvariabeln▪ if (this.parent == other.parent) … // Jämför pekarnas värden (0 == 49152),
// tittar inte efter något objekt// (Motsvarar operatorn "is" i Python)
▪ painter.draw(circle1) // Om circle1 == null,// får parametern till draw också värdet null
Inte använda fälten och metoderna i objektet den pekar på!▪ Den pekar ju inte på något objekt!▪ this.parent = null; // OK▪ this.parent.name = "Hello"; // Fel vid körning: NullPointerException
parent:
21
jonk
v@id
ajo
nkv@
ida
21Sammansättning 1 Anta att vi har en Point-klass:
public class Point {private double x, y;public Point(double x, double y) {
this.x = x;this.y = y;
}public double getX() {
return x;}public double getY() {
return y;}public double getDistFromOrigin() {
return Math.sqrt(x*x + y*y);}
}
22
jonk
v@id
ajo
nkv@
ida
22Sammansättning 2 Nu vill vi skapa en cirkelklass – två alternativ:
public class Circle {// Alla fält är primitiva typer, som tidigareprivate double x, y, r;public Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}…
}
class Circle {// Fält kan vara objektprivate Point center;private double r;public Circle(Point center, double r) {
this.center = center;this.r = r;
}…
}
Implementera allt från början
Använd existerande punktklassen!
Sammansättning =composition
23
jonk
v@id
ajo
nkv@
ida
23Sammansättning 3 Med sammansättning: En cirkel har en punkt, eller består av en punkt (och en radie) Återanvändning av existerande kod (Point kunde vara komplicerad) Mindre upprepning – bra!
Exempel i labben: Listor finns redan En kö har en lista
där den kan lagrasina element
class Circle {// Fält kan vara objektprivate Point center;private double r;public Circle(Point center, double r) {
this.center = center;this.r = r;
}…
}
Använd existerande punktklassen!
24
jonk
v@id
ajo
nkv@
ida
24Sammansättning och delegering Om man vill ge tillgång till "komponentens" funktionalitet:
Delegera!
class Circle {// Fält kan vara objektprivate Point center;private double r;public Circle(Point center, double r) {
this.center = center;this.r = r;
}public double getDistFromOrigin() {
return center.getDistFromOrigin();}…
}
Använd existerande punktklassen!
Vad är cirkelnsavstånd till origo?
Samma som punktens!
25
jonk
v@id
ajo
nkv@
ida
25Sammansatt objektstruktur 1 I vissa språk: Sammansatta objekt är sammansatta i minnet class Circle {
Point center;double radius;
} Circle c1 = new Circle();
Object header:
radius 0.0
(data)
c1yx
0.00.0 "Point-delen"
av en cirkel
26
jonk
v@id
ajo
nkv@
ida
26Sammansatt objektstruktur 2 Men javas objektvariabler är alltid pekare! Ett "sammansatt" objekt består alltid av flera fullständiga objekt class Circle {
Point center;double radius;
} Circle c1 = new Circle();
Object header:
radiuscenter
0.0
(data)
c1
Object header:
yx
0.0
(data)
0.0
En Circle består av– en Point-pekare (inte en Point)– en double
27
jonk
v@id
ajo
nkv@
ida
27Sammansatt objektstruktur 3 Detta har alla konsekvenser som vi såg för pekare tidigare Exempel: Två cirklar kan ha samma centrumobjekt Point center = new Point(10, 20);
Circle c1 = new Circle(center, 7);Circle c2 = new Circle(center, 12);
Object header:
radiuscenter
7.0
(data)
c1
Object header:
yx
20.0
(data)
10.0
Object header:
radiuscenter
12.0
(data)
c2
Vad ska {klassen, metoden, fältet} uppfylla?
29
jonk
v@id
ajo
nkv@
ida
29Kontrakt Kontrakt: Överenskommelse som anger Vad som ska tillhandahållas Vad som förväntas i utbyte Allmänna regler runt utbytet …
Inom objektorienterad programmering: Vilka värden kan en metod ta emot? Vad garanterar metoden att den gör, om den får sådana värden? Vad returnerar den? Vad garanterar en klass angående sitt tillstånd och beteende? …
30
jonk
v@id
ajo
nkv@
ida
30Kod kan innehålla (vissa) formella kontraktclass Circle {
private double x, y, r;public Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}public double getArea() {
return Math.PI * this.r * this.r ;}
}
Krav på input: Parametrarna måste vara av typ double
Löfte om resultattyp: Returnerar alltid double
Följer direkt från manifest typningSå vanligt att man oftast inte ens ser det som kontrakt
31
jonk
v@id
ajo
nkv@
ida
31Varför räcker inte koden?class Circle {
private double x, y, r;public Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}public double getArea() {
return Math.PI * this.r * this.r ;}
}
+
Koden definierar exakt vad programmet gör!
Varför räcker inte detta?
32
jonk
v@id
ajo
nkv@
ida
32Varför räcker inte koden? (2)class Circle {
private double x, y, r;public Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}public double getArea() {
return Math.PI * this.r * this.r ;}
}
+
Svårt att inse alla konsekvenserav tusentals rader kod
Kontraktet bör sammanfattavad som garanteras, krävs
33
jonk
v@id
ajo
nkv@
ida
33Varför räcker inte koden? (3) Vi är inte intresserade av vad koden gör! Mycket viktig konceptuell skillnad mellan:
Vad vi faktiskt gör(koden)
Vad vi lovar att göra,och att fortsätta göra
i all evighet
(kontraktet)
Buggar
Implem
entations-detaljer
Implem
entations-detaljer
Buggar
34
jonk
v@id
ajo
nkv@
ida
34Exempel 1: Sortering Exempel: Sortera strängar Input:
▪ [diverse, test, input, något, sortera]
Nu vill vi sortera:▪ Primärt – efter längd▪ Sekundärt, om orden är lika långa – i bokstavsordning
Vi vill alltså få:▪ [test, input, något, diverse, sortera]
5 tecken 7 tecken
bokstavsordning inom varje grupp
35
jonk
v@id
ajo
nkv@
ida
35Exempel 1: Metod En metod: Börja med en lista ord
▪ [diverse, test, input, något, sortera]
Sortera i bokstavsordning utan att tänka på längd▪ [diverse, input, något, sortera, test]
Sortera i längdordning utan att tänka på bokstäverna▪ Generellt finns 4 möjliga resultat:
[test, input, något, diverse, sortera][test, något, input, diverse, sortera][test, input, något, sortera, diverse][test, något, input, sortera, diverse]
▪ Med stabil sortering: Byt bara ordning på två element om det krävs[test, input, något, diverse, sortera]
Vi tänker bara på längdenOrd med samma längd kan kastas om
input fortfarande före någotdiverse fortfarande före sortera
Löser vårt problem!
36
jonk
v@id
ajo
nkv@
ida
36Exempel 1: Vad kan vi se i koden? Anta att en lista kan sortera sig Men det finns inget uttryckligt kontrakt måste läsa koden
class List {…void sort() {
for (int i=0; i < strings.length-1; i++){for (int j=1; j < strings.length-i; j++){
if (strings[j-1].compareTo(strings[j]) > 0) {String temp = strings[j-1];strings[j-1] = strings[j];strings[j] = temp;
}}
}}
}
Aha – sort() kör bubble sort, som är stabil! Då utnyttjar vi det!
37
jonk
v@id
ajo
nkv@
ida
37Exempel 1: Vad är tillåtet? Senare: Någon vill förbättra listklassen! Bubbelsortering är ineffektivt
class List {…
void sort() {// Utför bubble sort// (råkar vara stabil)……
}}
class List {…
void sort() {// Utför heap sort// (snabbare, men inte stabil)//…
}}
Om vi har detta… Får vi skriva om så här?
Andra kanske förlitar sig på egenskaper koden "råkade" ha dilemma!
38
jonk
v@id
ajo
nkv@
ida
38Kontrakt 1 Undvik genom kontrakt! Vissa språk har formellt stöd – t.ex. Eiffel
Ofta får man istället använda dokumentationen Idealet: Bara det som står i kontraktet gäller – titta aldrig på koden!
class List {/** Sorterar listan efter ordlängd. */void sort() { … }
}
Här står inget om stabilitet.
Då kan vi inte förutsätta det!
set_hour (new_hour: INTEGER)-- Set `hour' to `new_hour'require
valid_argument: 0 <= new_hour and new_hour <= 23do
hour := new_hourensure
hour_set: hour = new_hourend
precondition
postcondition
39
jonk
v@id
ajo
nkv@
ida
39Kontrakt 2 Ju tydligare, desto bättre…
class List {…
/** Sorterar listan efter ordlängd.Stabilitet garanteras inte.
*/void sort() {
…}
}
Beskriv gärna mer omvad koden lovar och inte lovar
40
jonk
v@id
ajo
nkv@
ida
40Exempel 2: Vad utlovas? Får jag ("Cirkel-användare") skicka in en negativ radie här? Ser inget som skulle orsaka problem… Men vem vet hur klassen kan ändras i framtiden?
class Circle {double x, y, r;
Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}}
41
jonk
v@id
ajo
nkv@
ida
41Exempel 2: Vad är tillåtet? Får jag ("Cirkel-utvecklare") ändra min kod så här? Verkar rimligt att cirklar ska ha positiv radie Men kod som förut fungerade kommer nu att krascha!
class Circle {double x, y, r;
Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}}
class Circle {double x, y, r;
Circle(double x, double y, double r) {if (r <= 0.0) throw …;this.x = x;this.y = y;this.r = r;
}}
42
jonk
v@id
ajo
nkv@
ida
42Exempel 2: Kontrakt? Med kontrakttänkande:
class Circle {double x, y, r;/** Skapar en cirkel med angivna
koordinater och radie.*/
Circle(double x, double y, double r) {this.x = x;this.y = y;this.r = r;
}}
Metoden tar emot double.
Det står inget om begränsningar.
Alltså lovar den att klaragodtycklig double.
43
jonk
v@id
ajo
nkv@
ida
43Exempel 2: Kontrakt? Med kontrakttänkande:
class Circle {double x, y, r;/** Skapar en cirkel med angivna
koordinater och radie. Radienmåste vara strikt positiv.
*/Circle(double x, double y, double r) {
this.x = x;this.y = y;this.r = r;
}}
Lovar att klara strikt positiva radier.
Kräver sådan input.
Skickar du in annat är beteendetodefinierat (kan krascha, …)
Grundregel för kontrakt:
Dokumentera alltid vad koden kräveroch vad den lovar
Relaterad grundregel:
Dokumentera inte vad koden görutan vad den ska göra
(och gärna varför)
Vi återkommer till kontrakt och löften flera gånger!
47
jonk
v@id
ajo
nkv@
ida
47API API: Application Programming Interface Specifikation av hur en applikation kan använda / kommunicera med
t.ex. operativsystemet, andra program, klassbibliotek, osv.
48
jonk
v@id
ajo
nkv@
ida
48Javas klassbibliotek Javas standardiserade klassbibliotek – "Java Standard Edition API" 4241 färdiga klasser inom många områden Standardiserade fält, metoder, …
49
jonk
v@id
ajo
nkv@
ida
49Dokumentation Dokumentation: http://docs.oracle.com/javase/8/docs/api/ Skriven för att kunna implementeras igen av någon annan,
bara genom att utgå ifrån beskrivningen! API-beskrivningen ska vara ett fullständigt kontrakt
för exakt vad som krävs av varje klass och metod
51
jonk
v@id
ajo
nkv@
ida
51Annoteringar 1 Annotateringar låter oss addera metadata till deklarationer Metadata – inte kod, utan information om kod Associeras med klasser, metoder, variabler, parametrar, …
import javax.annotations.Generated;
public class MyGUI {@Generatedprivate JButton closeButton;
@Generatedprivate void setup() {
… }
}
Medlemmarna har genereratsav ett verktyg
(t.ex. en GUI-byggare)
52
jonk
v@id
ajo
nkv@
ida
52Annoteringar 2 Exempel: Kod som är ”deprecated” Gammal, föråldrad, bör inte användas längre Deprecate = uttrycka ogillande
@Deprecatedvoid deprecatedMethod() {
…}
void useMeInstead() {…
}
Används metoden ändå:Kompilatorn kan varna
53
jonk
v@id
ajo
nkv@
ida
53Annoteringar 3 Vissa annoteringar kan definiera eller stärka formella kontrakt
import org.jetbrains.annotations.NotNull;import org.jetbrains.annotations.Nullable;public class TimeTools {
@NotNullpublic static String getTimeString() {
…return …;
}
public static String getTimeString(@Nullable Date date) {…return …;
}}
Metoden kan inte returnera nullAnvänds av dataflödesanalys,
påverkar varningar
Parametern får vara null metodkoden måste ta hand
om null-värden
(access modifiers)
55
jonk
v@id
ajo
nkv@
ida
55Bakgrund Tänk er en lista
som garanterar att elementen är i sorterad ordning!
class SortedList {String[] elements;int size;
String get(int pos) { return … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}
int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
}
Lagring för alla element
… med dessa hjälpmetoder
Stoppar in element på rätt plats…
Hämtar element
56
jonk
v@id
ajo
nkv@
ida
56Att gömma information Ofta vill vi ”gömma” delar av klasser och objekt
class SortedList {String[] elements;int size;int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
String get(int pos) { return … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}}
Syns bara inuti
själva klassen
Synligt utåt
57
jonk
v@id
ajo
nkv@
ida
57Gömma: För att inte förvirra användarna Mindre synligt mer överskådligt
class SortedList {String[] elements;int size;int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
String get(int pos) { return … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}}
Användaren behöveraldrig anropa
findNewPos eller insertAt
Att de syns förvirrar,gör klassen oöverskådlig!
Detta måsteanvändarna känna till
för att använda klassen
58
jonk
v@id
ajo
nkv@
ida
58Gömma: Minska åtaganden (kontrakt) Det vi har visat upp, måste vi normalt ha kvar
class SortedList {String[] elements;int size;int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
String get(int pos) { return … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}}
Användarna behöver inte komma åt element via
list.elements!
Göm det enbart get/add används
vi kan byta ut restenom vi vill frihet!
Detta ska utnyttjasav användarna,
måste visas och finnas kvar
59
jonk
v@id
ajo
nkv@
ida
59Gömma: Minska åtaganden (kontrakt) Det vi har visat upp, måste vi normalt ha kvar
class SortedList {String[] elements;int size;int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
String get(int pos) { return … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}}
Användarna behöver inte komma åt element via
list.elements!
Göm det enbart get/add används
vi kan byta ut restenom vi vill!
Detta ska utnyttjasav användarna,
måste visas och finnas kvar
class SortedList {ListNode first;ListNode findNewPositionFor(String el) { … }void insertElementAt(ListNode pos, String el) { … }String get(int pos) { return … }void add(String el) {
ListNode pos = findNewPositionFor(el);insertElementAt(pos, el);
}}
Den "publika" delen har kvar samma
signatur
60
jonk
v@id
ajo
nkv@
ida
60Gömma: För att uppfylla vårt kontrakt /**
* This class maintains a sorted list of elements.* As long as the contents of an element does not change,* elements will always be in sorted order.*/class SortedList {
String[] elements;int size;int findNewPositionFor(String el) { … }void insertAt(int pos, String el) { … }
void add(String el) {int pos = findNewPositionFor(el);insertAt(pos, el);
}}
Om användare kan anropa insertAt med fel position
blir listan osorterad
Då bryter vi vårt löfte!
Hur gömmer vi information?
62
jonk
v@id
ajo
nkv@
ida
62Att gömma data i Java Många OO-språk tillåter oss att gömma data I Java kan klasser, gränssnitt, fält och metoder vara:
▪ public – alla har tillgång▪ protected – tillgång i underklasser + andra i samma paket▪ [nothing] – tillgång i samma paket (används sällan)▪ private – tillgång inom samma klass
public class SortedList {private String[] elements;private int size;private int findNewPositionFor(String el) { … }private void insertElementAt(int pos, String el) { … }public void add(String el) {
int pos = findNewPositionFor(el);insertElementAt(pos, el);
}} Skapa ett stabilt gränssnitt för "allmänheten": add()
Göm all info om implementationsdetaljer
Vad hade private betytt utan OO?
Vi lovar mindre i vårt kontrakt!
63
jonk
v@id
ajo
nkv@
ida
63Inkapsling
Fundamentalt i OO “Objekt: en kapsel som innehåller
både data och funktioner”
Koppla ihop data och funktioner Begränsa tillgång till medlemmar
Genom accessmodifierare “Vissa medlemmar är instängda
i en ogenomskinlig kapsel,och kan inte ses eller utnytttjasfrån utsidan”
Två betydelser hos…
Inkapsling (Encapsulation)
64
jonk
v@id
ajo
nkv@
ida
64Privata fält Vanlig princip: Fält är implementationsdetaljer, ska vara privata Om det verkligen är rimligt att andra klasser ska komma åt fältvärden:
▪ Skapa en public accessor-metod (getter) vid behovSkapa en public mutator-metod (setter) vid behov
private double diameter;/** Set the radius to r (must not be negative). */public void setRadius(final double radius) {
if (r >= 0.0) diameter = 2 * radius;else throw new IllegalArgumentException("Negative radius: " + r);
}
Kan ändra intern representation:Ändra bara getter/setter, som är i samma klass
Kan lägga till konsistenskontroll
65
jonk
v@id
ajo
nkv@
ida
65Namngivning: Getter, Setter Namngivning:
private double radius;private boolean visible;
/** Set the radius to r (must not be negative). */public void setRadius(final double r) {
if (radius >= 0.0) radius = r;else throw new …;
}
public double getRadius() {return radius;
}public boolean isVisible() {
return visible;}
Setters:void setProperty(…)
Getters:getProperty()
Booleska getters:isProperty()
Mer info: http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html
66
jonk
v@id
ajo
nkv@
ida
66Tillåtna publika fält Vissa anser att det finns undantag ”Rena” datastrukturer
(inte mycket beteende, osannolikt att det skulle ändras i framtiden)
public class Dimension {public int width;public int height;
}
68
jonk
v@id
ajo
nkv@
ida
68Tre sorters variabel
Deklareras i en metod
Varje metodanrophar sin egen "kopia"
Två anrop till foo() egna värden på x
Anropet avslutas variabeln frigörs
Lokal variabel:
Deklareras i en klass Varje instans (objekt)
har sin egen "kopia" Två olika objekt
egna värden på x Två anrop samma x! Objektet slängs bort
variabeln frigörs
Fält:
I en klass, static
Varje programkörninghar sin egen "kopia"
Ett enda värde lagras,i klassen istället föri ett objekt
Statiskt fält:
public class MyProg {public void foo() {
int x = calcX();…
}}
public class MyProg {int x;public void foo() {
drawAt(x); …}
}
public class MyProg {static int x;public static void foo() {
print(x); …}
}
Olika lagring, olika livstider!
Inte ett intuitivtnyckelord!
69
jonk
v@id
ajo
nkv@
ida
69Statiska fält 1: Namngivna konstanter Konstanter bör (nästan) alltid namnges Jämför läsbarhet:
▪ for (int i = 1; i <= 52; i++) {…
}
Alternativt:▪ for (int i = 1; i <= deckSize; i++) {
…}
Mycket viktigtför programunderhåll!
70
jonk
v@id
ajo
nkv@
ida
70Statiska fält 2: Namngivna konstanter Namngivna konstanter läggs oftast på klassnivå (static)
▪ public class Circle {public static final double PI =
3.1415926535897932384626434;…
}▪ Circle c1 = new Circle(1, 2, 3);
Circle c2 = new Circle(10,11,12);
Header:
yx
2
(data)1
r 3
c1Static field PI
getArea
getCircum
…code…
…code…
setRadius …code…
c2
Header:
yx
11
(data)10
r 12
jonkv.graphics.Circle
Namngivna konstanter:static – i klassen
final – ändras intenamn – stora bokstäver
(WITH_UNDERSCORE)
Lagras en gång slösar inte utrymme
3.14159…
71
jonk
v@id
ajo
nkv@
ida
71Statiska fält 3: "Globala" variabler Kan också användas till "globala" variabler, åtkomliga överallt
Varning!
Globala variabler ger ofta problem!
Använd dem bara i undantagsfall!
72
jonk
v@id
ajo
nkv@
ida
72Statiska fält 4: Exempel Exempel: Hålla reda på antal cirklar som skapats
▪ public class Circle {public static final double PI = 3.14159; // constant pipublic static int circlesCreated = 0; // how many are created?public double x, y, r;public Circle(double x, double y, double radius) {
this.x = x; this.y = y; this.r = radius; circlesCreated++;
} }
▪ Circle c1 = new Circle(1, 2, 3);Circle c2 = new Circle(10,11,12);
Header:
yx
2
(data)1
r 3
c1Static field circlesCreated
Static field PIc2
Header:
yx
11
(data)10
jonkv.graphics.Circle
getArea
getCircum
…code…
…code…
setRadius …code…
73
jonk
v@id
ajo
nkv@
ida
73Statiska fält 5: Att referera till dem För att referera till ett statiskt fält:
▪ public class Circle {public static final double PI = 3.14159; // constant pipublic static int circlesCreated = 0; // how many are created?public double x, y, r;public Circle(double x, double y, double radius) {
this.x = x; this.y = y; this.r = radius; circlesCreated++;
} }
▪ public class CircleTest {public static void main(String[] args) {
System.out.println("Circles created: " + Circle.circlesCreated);System.out.println("Pi is: " + Circle.PI);
}}
Här räcker "circlesCreated",eftersom fältet är i samma klass
Här använder vi klassnamn.fält
74
jonk
v@id
ajo
nkv@
ida
74Statiska fält 6: Inte så här För att referera till ett statiskt fält: Inte så här:
▪ Circle c = new Circle();System.out.println("Circles created: " + c.circlesCreated);
Missvisande:Ser ut som att circlesCreated är ett "vanligt" instansfält!