java and oop - ida · 2016. 1. 21. · en klass i java 4 jonkv@ida för att lagra info om cirklar...
TRANSCRIPT
[email protected] – 2016
TDDD78Introduktion till OOP i Java
3
jonk
v@id
ajo
nkv@
ida
3Klasser Bilar är komplicerade – vi tar cirklar som exempel (ritprogram?)
4
jonk
v@id
ajo
nkv@
ida
4En klass i Java För att lagra info om cirklar som objekt i Java: Skapa en cirkelklass
class Circle {
}
Circle.java
Varje Java-klass är i sin egen fil, med "samma" namn(Avancerat undantag: nästlade klasser)
Klassnamn använder "CamelCase":ArrayList, ProcessBuilder, StackTraceElement
I singular:Inte ”Circles”, ”Towers” eller ”ArrayLists”!
Definiera fält (se del 2)
Definiera konstruktorer (se del 4)
Definiera metoder (se del 3)
Medlemmar
6
jonk
v@id
ajo
nkv@
ida
6Egenskaper Vi har nämnt att mojänger/objekt har egenskaper Vissa kan vara konstanta, andra kan ändras efter att objektet skapas
Längd/höjdFärg
MotorstyrkaToppfart
Nuvarande fartKvarvarande bränsle
Koordinater (x,y)Radie (r)
7
jonk
v@id
ajo
nkv@
ida
7Fält i en klass Realisera egenskaperna som fält (medlemsvariabler) i en klass
class Circle {double x, y;double r;
}
Circle.java
All kod för klassenär inuti klassdeklarationen
Ange datatyp för varje fält:double = 64-bitars flyttal
Detta är en klasssom talar om vilken sorts information
alla cirkelobjekt ska innehålla
Ännu har vi inte skapat någon cirkel!
medlemsvariabel = member variablefält = field
klass = class
8
jonk
v@id
ajo
nkv@
ida
8Namngivning Namngivning för fält: Ge beskrivande namn
▪ x,y,r – OK, vedertagna förkortningar▪ temp, foo, bar – inte bra, vad är detta?▪ index – eller selectedIndex?▪ left – eller livesLeft?▪ s=52 – eller deckSize=52?▪ …
Variabler, fält, metoder: allaUtomFörstaBörjarMedStor▪ main(), args, tvåPlusTvå, out, addElement(), arrayLength, …
Använd Javas standard!
Bra namn färre kommentarer
behövs!
Sträva efter självdokumenterande
kod!
9
jonk
v@id
ajo
nkv@
ida
9
Datorns minne
Fält i objekt Varje objekt vi skapar får sin egen kopia av fälten Alla cirklar har en radie Alla cirklar har varsin radie
(Hur skapar man objekt?Med "new" – detaljer diskuteras senare!)
Object header:
yx
4.512
(data)
12.7
r 0.0002
Object header:
yx
3.222
(data)
23.9
r 12.7
8-16 bytes "intern info"
för Java
3*8=24 bytes för fälten
[Python2: Overhead
>300 bytes,fält 72 bytes]
10
jonk
v@id
ajo
nkv@
ida
10Tillstånd (state) Varje objekt har ett nuvarande tillstånd (state) Avgörs av nuvarande värdet
på samtliga fält(även de konstanta)
Datorns minne
Object header:
yx
4.512
(data)
12.7
r 0.0002
Object header:
yx
3.222
(data)
23.9
r 12.7
Två distinkta objekt
med olikatillstånd
tillstånd = state
11
jonk
v@id
ajo
nkv@
ida
11
Datorns minne
Samma tillstånd Två distinkta objekt i minnet kan ha samma tillstånd Precis som två variabler
kan ha samma värde▪ x=10
y=10▪ x = y, men x och y är ändå olika variabler!
Object header:
yx
4.512
(data)
12.7
r 0.0002
Object header:
yx
4.512
(data)
12.7
r 0.0002
Python:a = ("hello", "world")b = ("hello", "world") två olika listor
med samma element
b.append("again") bara b ändras, inte a a och b var olika listor på
olika plats i minnet
Samma tillstånd,men inte samma objekt
12
jonk
v@id
ajo
nkv@
ida
12
Datorns minne
Byta tillstånd I många klasser kan objekten byta tillstånd när tiden går
Object header:
yx
4.512
(data)
12.7
r 0.0002
Datorns minne
Object header:
yx
8.328
(data)
12.7
r 0.0002
Fortfarande samma objekt – men nytt tillstånd!
Ändra värdet på y
13
jonk
v@id
ajo
nkv@
ida
13Final Om ett fält inte får/ska ändras efter att objektet skapats: Deklarera det final
class Circle {final double x, y;final double r;
}
Circle.java
class Person {final String personnummer;Person(String personnummer) {
this.personnummer = personnummer;}
}
Person.java
Allt är final klassens objekt är immutable
(≈ oföränderliga)
14
jonk
v@id
ajo
nkv@
ida
14Punktnotation Använd punkt för att komma åt ett fält i ett objekt Fler exempel när vi pratar om metoder
class Circle {double x, y;double r;static void print(Circle circ) {
System.out.println("Hey! You gave me a circle!");System.out.println("Its radius is " + circ.r);
}}
Circle.java
15
jonk
v@id
ajo
nkv@
ida
15Att gömma data Fält har skyddsnivåer: private – bara klassens egna metoder kan komma åt fältet
▪ Klassen har full kontroll – oftast bra!
public – alla kan komma åt fältet▪ T.ex. svårt att ändra datatyp senare – annan kod kan sluta fungera
(protected, "package-protected"… – senare)
public class Circle { // Klasser är oftast publicprivate double x, y;private double r;
}
Circle.java
Vi ignorerar detta i många exempel – återkommer senare…
Princip:Ju färre som kommer åt något,
desto enklare att verifiera, ändra
17
jonk
v@id
ajo
nkv@
ida
17Beteenden
Objekt i verklighetengör saker, har beteenden
Reaktivt, på begäran:Tryck på tutan bilen tutar
Spontant, "aktivt":Kamelen väljer att spotta
Uppnås via metoder (methods)som kan anropas
Inte del av "vanlig" OOSe multitrådning
18
jonk
v@id
ajo
nkv@
ida
18Metoder Varje cirkel ska kunna beräkna sin area Deklarera en metod som returnerar detta
public class Circle {private double x, y;private double r;public double getArea() {
return Math.PI * r * r;}public void setRadius(double newR) {
r = newR;}
}
Circle.java
Metoder placeras oftast efter fält
Metod utan sidoeffekter:Påverkar inget, informerar bara
Metod med sidoeffekter:Ändrar något
(i detta objekt / på annan plats)
Alltid ett returvärde(typ eller void)
Parametrar hartyper, namn
sidoeffekt = side effect
19
jonk
v@id
ajo
nkv@
ida
19Metodkroppen I metodens kropp (body) anges vad metoden ska göra Som i en "vanlig" funktion – med en skillnad:
public class Circle {private double x, y;private double r;public double getArea() {
return Math.PI * r * r;}public void setRadius(double newR) {
r = newR;}
}
Circle.java
Kan direkt komma åt objektets fält!
…Men i vilket objekt?
Vi deklarerar "r" en enda gång.Vi kan skapa 1000 cirklar,
och var och en har en egen radie!
20
jonk
v@id
ajo
nkv@
ida
20This 1: Detta objekt Om vi tar bort "förkortningar":
Ett objekt kan ha många "namn",giltiga i olika delar av koden!
public class Circle {private double x, y, r;public double getArea() {
return Math.PI * this.r * this.r ;}public static void main(String[] args) {
Circle c1 = …;Circle c2 = …;double a = c1.getArea(); double b = c2.getArea();
}}
Circle.java
Fältet "r" i objektet "this"…men vad är "this"?
"this" är objektet vars metod anropades!I första anropet: this är samma objekt som c1I andra anropet: this är samma objekt som c2
"r" är en förkortning för "this.r"
21
jonk
v@id
ajo
nkv@
ida
21This 2: Omskrivning Nästan som om kompilatorn skrev om koden Adderade en this-parameter till varje metod
public class Circle {private double x, y, r;public double getArea(Circle this) {
return Math.PI * this.r * this.r;}public static void main(String[] args) {
Circle c1 = …;double a = getArea(c1);
}}
public class Circle {private double x, y, r;public double getArea() {
return Math.PI * this.r * this.r ;}public static void main(String[] args) {
Circle c1 = …;double a = c1.getArea();
}}
(Nästan: Det finns viktiga skillnader, t.ex. i ärvning)
"Implicit parameter":this
22
jonk
v@id
ajo
nkv@
ida
22This 3: Utelämna this Kan ofta utelämna this Givet en identifierare "r" söker kompilatorn efter:
1. Lokala variabler och parametrar "r"2. Fält "r"
public class Circle {private double x, y, r;public double getArea() {
return Math.PI * r * r;}public static void main(String[] args) {
Circle c1 = …;double a = c1.getArea();
}}
public class Circle {private double x, y, r;public double getArea() {
return Math.PI * this.r * this.r ;}public static void main(String[] args) {
Circle c1 = …;double a = c1.getArea();
}}
"Det finns inget r,så de måste mena
this.r…"
23
jonk
v@id
ajo
nkv@
ida
23This 4: Gömda fält Men variabler och parametrar gömmer fält ("hiding")
public class Circle {private double x, y, r;public void setRadius2(double r) {
System.out.println(r); // Finns variabel/parameter? Ja! Skriv ut denSystem.out.println(this.r); // Måste vara fältetr = r; // Sätter argumentet till sitt eget värde…this.r = r; // Sätter fältets värde
}}
public class Circle {private double x, y, r;public void setRadius2(double newR) {
System.out.println(r); // Finns variabel/parameter? Nej! Skriv ut fältetr = newR; // Sätter fältets värde
}}
Olika namn (r, newR)
Samma namn (r), parameter gömmer fält
24
jonk
v@id
ajo
nkv@
ida
24Namngivning Namngivning: Som för fält: Ge beskrivande namn
▪ update() eller movePlayer()?▪ doIt() eller shuffleDeck()?▪ units() eller setUnitType()?▪ …
Variabler, fält, metoder: allaUtomFörstaBörjarMedStor▪ main(), args, tvåPlusTvå, out, println()▪ addElement(), arrayLength, …
Använd Javas standard!
25
jonk
v@id
ajo
nkv@
ida
25Namngivning 2: Overloading Metoder kan överlagras (overloading) Olika metoder i samma klass med samma namn
Användning:▪ När metoderna gör i princip samma sak▪ När det vore onödigt krångligt att hitta på egna namn
(printInt, printDouble, …)
public class Printer {public void print(int val) { … } public void print(double val) { … } public void print(double val, int precision) { … }
}Skiljs åt av antal argument +
argumenttyperna
26
jonk
v@id
ajo
nkv@
ida
26Metodlängd (1) Hur lång får en metod vara? "The first rule of functions is that they should be small.
The second rule of functions is that they should be smaller than that.Functions should not be 100 lines long.Functions should hardly ever be 20 lines long."▪ -- Robert Martin, Clean Code: A Handbook of Agile Software Craftsmanship
"The routine should be allowed to grow organically up to 100-200 lines.Decades of evidence say that routines of such length[are] no more error prone than shorter routines."▪ -- Steve McConnell, Code Complete
27
jonk
v@id
ajo
nkv@
ida
27Metodlängd (2) Varför dessa motsatser?
Ju fler kockar desto sämre soppa
Fyra ögon ser bättre än två
För varje regel finns en lika stark och motsatt motregel…
28
jonk
v@id
ajo
nkv@
ida
28Metodlängd (3) Målet: Kod ska vara läsbar, lätt att förstå, lätt att underhålla Långa metoder varningssignal!
▪ Är metoden osammanhängande? Gör den för mycket?▪ Kanske det finns meningsfulla delar som kan bli egna metoder!
Många korta metoder varningssignal!▪ Är det för många metoder för att hålla reda på?▪ Skulle det bli enklare om man kombinerade dem?
Hitta rätt balansPrioritera målet (läsbarhet) istället för medlet (uppdelningen)
Men:"För osammanhängande" metoder metoder är vanligare i inlämningar,
kan ge komplettering
30
jonk
v@id
ajo
nkv@
ida
30Skapande Att skapa nya listor, tupler osv. i Python:
tomLista = []minLista = ["a", "b", "c"]minTupel = (12, 34, 56)minDict = { "a": 1, "b": 2 }
Egen syntax för varje typ
Ange alla elementsom listan / tupeln / …
ska innehålla
31
jonk
v@id
ajo
nkv@
ida
31Skapa objekt 1 Hur skapar man nya objekt?
Datorns minne
Object header:
yx
4.512
(data)
12.7
r 0.0002
Nej: Många klasser har fältsom ska beräknas
eller kan lämnas tommaeller är privata för internt bruk
Måste kunna välja vilka fält vi sätter
Circle myCircle =Circle[[12.7, 4.512, 0.0002]];
Generell "objektsyntax",ange värdet på varje fält?
32
jonk
v@id
ajo
nkv@
ida
32Skapa objekt 2 Hur skapar man nya objekt?
Datorns minne
Object header:
yx
0
(data)
0
r 0
Nej: Tillåter godtyckliga värdenListor kan innehålla vad som helst
Men cirklar ska ha radie > 0Klassen ska kunna garantera detta!
Circle myCircle;myCircle.x = 10;myCircle.y = 20;
…
Först skapa "nollställt" objekt,med alla fält "nollställda",
sedan sätta önskade värden utifrån?
Fundamental princip:“Klassen bestämmer över sina objekt”
(kan förhindra manipulation utifrån
33
jonk
v@id
ajo
nkv@
ida
33Konstruktorer 1 Låt klassen ange konstruktorer,
speciella metoder för att initialisera objekt
public class Circle {private double x, y, r;
public Circle(double x, double y, double radius) {………
}}
Ingen returtyp (inte void!)Samma namn som klassen Detta är en konstruktor!
konstruktor = constructor
34
jonk
v@id
ajo
nkv@
ida
34Konstruktorer 2 Ibland vill vi: Kunna sätta specifika värden på alla fält
public class Circle {private double x, y, r;
public Circle(double x, double y, double radius) {this.x = x;this.y = y;this.r = radius;
}}
En parameter per fält
En tilldelning per fält;"this" är det nya objektet
public static void main(String[] args) {Circle c1 = new Circle(10.0, 20.0, 14.2);
}
Vi anropar konstruktornmed new
och anger lämpliga parametrar
35
jonk
v@id
ajo
nkv@
ida
35Konstruktorer 3: Vad händer? 1: Minne allokeras (reserveras) för objektet
2: Alla fält får defaultvärden Heltal: 0 Floating point: 0.0 Boolean: false Objekt: null (diskuteras senare)
3: Konstruktorn anropas
Object header:
yx
(skräp)
(skräp)
(skräp)
r (skräp)
Object header:
yx
0.0
Circle…0.0
r 0.0
Circle(double x, double y, double radius) {this.x = x;this.y = y;this.r = radius;
}
Fundamental princip:“Klassen bestämmer över sina objekt” – klassen anger konstruktorkoden!
36
jonk
v@id
ajo
nkv@
ida
36Konstruktorer 4: Kontroller Ibland vill vi: Kontrollera att bara tillåtna värden anges
public class Circle {private double x, y, r;
public Circle(double x, double y, double radius) {if (radius <= 0.0) {
throw …signalera fel…;}this.x = x;this.y = y;this.r = radius;
}}
Se till att radien > 0,annars avbryts konstruktorn inget objekt skapas
37
jonk
v@id
ajo
nkv@
ida
37Konstruktorer 5 Ibland vill vi: Ta in värden i annat format än det klassen använder
public class Circle {private double x, y, r;
public Circle(Point center, double radius) {if (radius <= 0.0) throw …;this.x = center.x;this.y = center.y;this.r = radius;
}}
Ta ut x och yfrån "centrumpunkten"
Anta en "punktklass"som lagrar x, y
38
jonk
v@id
ajo
nkv@
ida
38Konstruktorer 6 Ibland vill vi: Beräkna värden på fält från andra parametrar
public class Circle {private double x, y, r;private double area;
public Circle(double x, double y, double circumference) {if (circumference<= 0.0) throw …;this.x = x;this.y = y;this.r = circumference / (2*Math.PI); this.area = Math.PI * r * r;
}}
Beräkna radie från omkrets
Beräkna area från radie
39
jonk
v@id
ajo
nkv@
ida
39Konstruktorer 7 Ibland vill vi: Sätta värden själva eftersom de är "interna" detaljer,
inte något som anroparen ska bry sig ompublic class Circle {
private double x, y, r;private int timesPainted;
public Circle(double x, double y, double radius) {this.x = x;this.y = y;this.r = radius;this.timesPainted = 0;
}}
Håll reda på antalet gångervi har ritat cirkeln (statistik)
Från början är antalet alltid 0
40
jonk
v@id
ajo
nkv@
ida
40Konstruktorer 8 En konstruktor kan göra vad som helst
public class Circle {private double x, y, r;private boolean debugMode;public Circle(double radius) {
System.out.println("Hello, world!");System.exit(0);
}}
Inte vad man ska göra,men man kan
41
jonk
v@id
ajo
nkv@
ida
41Konstruktorer 9: Kopiering Ibland kan man vilja kopiera objekt Konstruktor som tar ett objekt av samma typ
public class Circle {private double x, y, r;public Circle(double x, double y, double radius) {
this.x = x;this.y = y;this.r = radius;
}public Circle(Circle other) {
this.x = other.x;this.y = other.y;this.r = other.r;
}}
Kopieringskonstruktor:Tar ett objekt av samma typ
42
jonk
v@id
ajo
nkv@
ida
42Konstruktorer 10: Overloading En klass kan ha flera konstruktorer Alla heter samma som klassen overloading
public class Circle {private double x, y, r;public Circle(double x, double y, double radius) {
this.x = x;this.y = y;this.r = radius;
}public Circle(Point center, double diameter) {
this.x = center.x;this.y = center.y;this.r = diameter / 2;
}}
43
jonk
v@id
ajo
nkv@
ida
43Konstruktorer 11: Minst en! Varje klass har minst en konstruktor Har du inte skrivit någon?
Då skapar Java en tom konstruktor utan argument!
public class Circle {private double x, y, r;
}
public class Circle {private double x, y, r;public Circle() {
// Gör ingenting// alla fält har defaultvärden (0, 0.0, false, …)
}}