TDDD78, TDDE30, 729A85 jonas.kvarnstrom@liu.se 2018 Introduktion till objektorienterad programmering i Java
Klasser 3 Bilar är komplicerade vi tar cirklar som exempel (ritprogram?)
En klass i Java 4 För att lagra info om cirklar som objekt i Java: Skapa en cirkelklass Varje Java-klass är i sin egen fil, med "samma" namn (Avancerat undantag: nästlade klasser) Circle.java Definiera fält (se del 2) Definiera konstruktorer (se del 4) Medlemmar Definiera metoder (se del 3) och vad ska klasser heta?
Namngivning: Varför viktigt? 5 Att använda namn, och ge beskrivande namn, ersätter till viss del kommentarer och dokumentation! Lättare och snabbare att skriva Lättare och snabbare att läsa Lättare att hålla uppdaterat man ser om namnet är "ur synk"
Klassnamn 6 Klasser är saker (substantiv) Namnges i singular create a new every has a Plural blir fel? every has... Klassnamn använder "CamelCase":
Egenskaper 8 Vi har nämnt att mojänger/objekt har egenskaper Vissa kan vara konstanta, andra kan ändras efter att objektet skapas Längd/höjd Färg Motorstyrka Toppfart Nuvarande fart Kvarvarande bränsle Koordinater (x,y) Radie (r)
Namngivning 9 Egenskaper och variabler ska ha beskrivande namn En lista som innehåller alla nätverksuppkopplingar: En egenskap som är sann om spelet är igång: OK, vedertagna förkortningar vad är detta? eller? eller? eller? Bra namn färre kommentarer behövs! Sträva efter självdokumenterande kod! Låt andra se, inte bara läsa om, hur det är kopplat
Deklarera fält i en klass 10 Realisera egenskaperna som fält (medlemsvariabler) i en klass All kod för klassen är inuti klassdeklarationen Circle.java En klass talar om vilken sorts information alla cirkelobjekt ska innehålla Ännu har vi inte skapat någon cirkel, bara en ritning eller stämpel! Ange datatyp för varje fält: double = 64-bitars flyttal medlemsvariabel = member variable fält = field klass = class
Fält i objekt 11 Varje objekt vi skapar får sin egen kopia av fälten Alla cirklar har en radie; varje cirkel har sin egen radie (Hur skapar man objekt? Med "new" detaljer diskuteras senare!) Datorns minne 8-16 bytes "intern info" för Java 3*8=24 bytes för fälten [Python2: Overhead >300 bytes, fält 72 bytes]
Tillstånd (state) 12 Varje objekt har ett nuvarande tillstånd (state) Avgörs av nuvarande värdet på samtliga fält (även de konstanta) Datorns minne Två distinkta objekt med olika tillstånd Varje objekt lagras på sin egen plats tillstånd = state
Samma tillstånd 13 Två distinkta objekt i minnet kan ha samma tillstånd Precis som två variabler kan ha samma värde Datorns minne, men och är ändå olika variabler! Python: två olika listor med samma element Samma tillstånd, men inte samma objekt bara b ändras, inte a a och b var olika listor på olika plats i minnet
Byta tillstånd 14 Objekt kan byta tillstånd Datorns minne Datorns minne Ändra värdet på y Fortfarande samma objekt men nytt tillstånd!
Inte byta tillstånd 15 Om ett fält inte får/ska ändras efter att objektet skapats: Deklarera det final Person.java Circle.java Allt är final klassens objekt är immutable ( oföränderliga)
Punktnotation 16 Använd punkt för att komma åt ett fält i ett objekt Fler exempel när vi pratar om metoder Circle.java
Att gömma data 17 Fält har skyddsnivåer: bara klassens egen kod kan komma åt fältet Klassen har full kontroll oftast bra! alla kan komma åt fältet T.ex. svårt att ändra datatyp senare annan kod kan sluta fungera (Fler varianter diskuteras senare) Princip: Färre som kommer åt något enklare att verifiera, ändra Circle.java
Välj rätt lagring 18 Alla möjliga värden är rimliga vi har gjort en feltyp omöjlig
Beteenden 20 Objekt i verkligheten gör saker, har beteenden Spontant, "aktivt": Kamelen väljer att spotta Inte del av "vanlig" OO Se multitrådning eller autonoma agenter (AI) Reaktivt, på begäran: Tryck på tutan bilen tutar Uppnås via metoder (methods) som kan anropas
Metoder 21 Varje cirkel ska kunna beräkna sin area Deklarera en metod som returnerar detta Metoder placeras oftast efter fält Circle.java Ange alltid vad som returneras (datatyp eller void) Parametrar har typer, namn
Metodkroppen 22 I metodens kropp (body) anges vad metoden ska göra Som i en "vanlig" funktion med en skillnad: 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!
this
This 1: Detta objekt 24 Om vi tar bort "förkortningar": Circle.java "r" är en förkortning för "this.r" 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 c1 I andra anropet: this är samma objekt som c2 Ett objekt kan ha många "namn", giltiga i olika delar av koden!
This 2: Omskrivning Nästan som om kompilatorn skrev om koden Adderade en this-parameter till varje metod 25 "Implicit parameter": this (Nästan: Det finns viktiga skillnader, t.ex. i ärvning)
This 3: Utelämna this 26 Kan ofta utelämna this Givet en identifierare "r" söker kompilatorn efter: 1. Lokala variabler och parametrar "r" 2. Fält "r" "Det finns inget r, så de måste mena this.r "
This 4: Gömda fält 27 Men variabler och parametrar gömmer fält ("hiding") Olika namn (r, newr) Samma namn (r), parameter gömmer fält
Varför vill vi dela upp koden i (flera) metoder?
Begrepp 29 Tidigare nämnde vi egna datatyper som nya begrepp Det finns redan heltal, flyttal, sanningsvärden, Vi inför själva begreppet kund, bankkonto, Nya saker med egna namn, utökar vår vokabulär
Recept 30 Pannkaksreceptet lagapannkaka(), utan bakningsbegrepp: 1000 rader För handen till vispen och greppa den. Lyft vispen med handen medan du undviker att kollidera med andra föremål. För handen i cirkulära rörelser Omöjligt att läsa 3000 rader recept och förstå helheten! Inför nya meningsfulla begrepp: vispa, lagapannkaka(), enligt Arla: Vispa ut mjölet i hälften av mjölken till en slät smet. Vispa i resterande mjölk, ägg och salt. Låt smeten svälla ca 10 min. Smält smör i en stekpanna och häll ner i smeten. Grädda tunna pannkakor. Nu kan vi förstå receptet i sin helhet, på en högre nivå: Lagom långt, lagom abstraktionsnivå! Metoden vispa(): En ny uppgift med eget namn
Grundläggande och fördefinierade begrepp 31 När vi ska få datorn att göra något: Det finns redan uppgifter i språket Kontrollstrukturer loopar, villkor, Tilldelning av värden Jämförelser Det finns bibliotek av färdig funktionalitet färdiga begrepp System.out.println() att skriva ut något på skärmen
Begrepp och metoder 32 Kan bygga upp allt med ett minimalt antal begrepp Svårt att få översikt! Dela i flera metoder med tydligt eget ansvar skapa nya begrepp Lätt att se vad som händer under tick() Definiera nytt meningsfullt begrepp
Grundläggande och fördefinierade begrepp 33 Även korta mönster kan bli till egna begrepp System.out.println() att skriva ut något, med radbrytning efter Uppbyggt av primitivare begrepp! Kunde ha krävt att användaren anropade: System.out.print(x); System.out.newLine(); Men println är ett användbart eget begrepp! Även om det bara gäller 2 rader
Balansera metodstorlek 34 Hur långt ska vi gå? 1000 metoder med 2 rader i varje? Lätt att förstå varje enskild metod Svårt att förstå sammanhanget 2 metoder med 1000 rader i varje? Tvärtom. Hitta en balans!
Metodlängd (1) 35 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
Metodlängd (2): Motsatser 36 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
Metodlängd (3): Läsbarhet 37 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? Repetitiv? Gör den för mycket? Antagligen 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 balans Prioritera målet (läsbarhet) istället för medlet (uppdelningen) Men: "För osammanhängande" metoder, och repetitiv kod, är vanligare i inlämningar och ger ofta komplettering
Metodlängd (4): Uppdelning 38 Parts of methods can be extracted Dela upp nya begrepp/namn Förbättrar läsbarhet om segmenten är komplexa/långa (balans!) IDEA kan ibland hjälpa till: Refactor Extract Method
Namngivning
Namngivning 41 Namngivning: Ge beskrivande namn () eller ()? () eller ()? () missvisande om metoden returnerar en lista på förflyttningar () () Kan du bandita lite? Vi säger till objektet att göra något! playermovement()? Hey you, playermovement() for me! moveplayer()? Hey you, move player for me! better keybindingsadder()? addkeybindings()
Namngivning 2: Overloading 42 Metoder kan överlagras (overloading) Olika metoder i samma klass med samma namn Användning: Skiljs åt av antal argument + argumenttyperna När metoderna gör i princip samma sak När det vore onödigt krångligt att hitta på egna namn (,, )
Skapande 44 Att skapa nya listor, tupler osv. i Python: Egen syntax för listor, Ange alla element som listan / tupeln / ska innehålla
Skapa objekt 1 45 Hur skapar man nya objekt? Generell "objektsyntax", ange värdet på varje fält? Datorns minne Nej: Många klasser har fält som ska beräknas eller kan lämnas tomma eller är privata för internt bruk Måste kunna välja vilka fält vi sätter
Skapa objekt 2 46 Hur skapar man nya objekt? Först skapa "nollställt" objekt, med alla fält "nollställda", sedan sätta önskade värden utifrån? Datorns minne Nej: Tillåter godtyckliga värden Listor kan innehålla vad som helst Men cirklar ska ha radie > 0 Klassen ska kunna garantera detta! Fundamental princip: Klassen bestämmer över sina objekt (kan förhindra manipulation utifrån
Konstruktorer 1 47 Låt klassen ange konstruktorer, speciella metoder för att initialisera objekt Ingen returtyp (inte void!) Samma namn som klassen Detta är en konstruktor! konstruktor = constructor
Konstruktorer 2 48 Ibland vill vi: Kunna sätta specifika värden på alla fält En parameter per fält En tilldelning per fält; "this" är det nya objektet Vi anropar konstruktorn med new och anger lämpliga parametrar
Konstruktorer 3: Vad händer? 49 1: Minne allokeras (reserveras) för objektet 2: Alla fält får defaultvärden Heltal: Floating point: Boolean: Objekt: 3: Konstruktorn anropas Fundamental princip: Klassen bestämmer över sina objekt klassen anger konstruktorkoden!
Konstruktorer 4: Kontroller 50 Ibland vill vi: Kontrollera att bara tillåtna värden anges Se till att radien > 0, annars avbryts konstruktorn inget objekt skapas
Konstruktorer 5 51 Ibland vill vi: Ta in värden i annat format än det klassen använder Anta en "punktklass" som lagrar x, y Ta ut x och y från "centrumpunkten"
Konstruktorer 6 52 Ibland vill vi: Beräkna värden på fält från andra parametrar Beräkna radie från omkrets Beräkna area från radie
Konstruktorer 7 53 Ibland vill vi: Sätta värden själva eftersom de är "interna" detaljer, inte något som anroparen ska bry sig om Håll reda på antalet gånger vi har ritat cirkeln (statistik) Från början är antalet alltid 0
Konstruktorer 8 54 En konstruktor kan göra vad som helst Inte vad man ska göra, men man kan
Konstruktorer 9: Kopiering 55 Ibland kan man vilja kopiera objekt Konstruktor som tar ett objekt av samma typ Kopieringskonstruktor: Tar ett objekt av samma typ
Konstruktorer 10: Overloading 56 En klass kan ha flera konstruktorer Alla heter samma som klassen overloading
Konstruktorer 11: Minst en! 57 Varje klass har minst en konstruktor Har du inte skrivit någon? Då skapar Java en tom konstruktor utan argument!