Föreläsning 8 - del 1: Objektorienterad programmering (forts.) - Exempel Eva Blomqvist eva.blomqvist@liu.se Linköpings universitet Sweden December 1, 2013 1
Innehåll OO-programmering fortsättning Skapa objekt baserat på data q Reguljära uttryck (överkurs) Exempel December 1, 2013 2
Vad ska en klass innehålla? (repetition) En klass kan innehålla följande: q En klassdeklaration (obligatoriskt) public class MittKlassNamn { q Klass- och instansvariabler "globala variabler" som kan kommas åt från vilken metod som helst (i klassen om de är private, även från andra klasser om de är public) Skrivs gärna högst upp i klassens kropp q En eller flera konstruktorer metod som talar om vad som händer när ett nytt objekt (instans) av metoden skapas q Klass- och instansmetoder metoder som representerar klassens och instansernas beteende - vad kan den här typen av objekt göra? q En main-metod...om det här är "huvudklassen" varifrån programmet ska köras December 1, 2013 3
Exempel: klassen Person Klassdeklaration: public class Person { December 1, 2013 4
Exempel: klassen Person...eller: class Person { December 1, 2013 5
Exempel: klassen Person Klass- och instansvariabler: public class Person { //Klassvariabel public static int noofpersons = 0; //Instansvariabler public String fname; public String lname; public int year; December 1, 2013 6
Exempel: klassen Person...men tänk på principen om inkapsling, då är det bättre såhär: public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; December 1, 2013 7
Exempel: klassen Person Konstruktor: public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; December 1, 2013 8
Exempel: klassen Person En klassmetod: public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; public static int getnoofpersons(){ return noofpersons; December 1, 2013 9
Exempel: klassen Person En instansmetod: public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; public static int getnoofpersons(){ return noofpersons; public String getname (){ return fname + " " + lname; December 1, 2013 10
Exempel: klassen Person En till instansmetod: public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; public static int getnoofpersons(){ return noofpersons; public String getname (){ return fname + " " + lname; public void setlastname (String newname){ lname = newname; 11
Exempel i Eclipse... December 1, 2013 12
Sammanfattning av modifierare (rep.) Klasser q Offentlig - public q Pakettillgänglig - (om inget sägs) q Nästlade klasser (klass i klass) - private Metod i en klass q Offentlig - public q Pakettillgänglig - (om inget sägs) q Skyddad (åtkomst från subklasser + paketet) - protected q Privat för den klassen - private q Klassmetod (statisk metod) - static q Instansmetod - (om inte static) December 1, 2013 13
Sammanfattning av modifierare (rep.) Variabel q Offentlig - public q Pakettillgänglig - (om inget sägs) q Skyddad (åtkomst från subklasser + paketet) - protected q Privat för den klassen - private q Klassvariabel (statisk variabel) - static q Instansvariabel - (om inte static) q Konstant - final Tre beslut q Åtkomst (offentlig, paket, skyddad, eller privat)? q Klass- eller instans (-variabel/-metod)? q Möjlig att ändra? December 1, 2013 14
Läsa från fil (repetition) och skapa objekt December 1, 2013 15
Ett exempel Anta att vi vill läsa in information om personer från en fil istället för att låta användaren mata in informationen via terminalfönstret Uppgift: En person har ett förnamn, ett efternamn och ett födelseår Hur lagrar vi detta i en fil? q q q Vi får bestämma oss för ett filformat som passar Vad sägs om: varje rad i filen representerar en person, och de olika dataelementen skiljs åt med hjälp av "," Vi måste välja något tecken som inte kommer att förekomma i de data vi vill läsa in - så att vi inte blandar ihop data och "separator-tecknet" Exempel på filinnehåll (alt1.txt): Anna,Andersson,1986 Arvid,Bengtsson,1947 December 1, 2013 16
Ett exempel baserat på uppgift 2.1 Alternativt exempel q Varje dataelement har en egen rad i filen. Vi antar att en person alltid representeras av exakt tre rader. q Fil enligt detta alternativ (alt2.txt): Anna Andersson 1986 Arvid Bengtsson 1947 OBS I projektet får ni anta att ni vet vad filerna heter, var de ligger och formatet på data i filerna (ni får en fil av oss för att testa med), men ni får inte göra några antaganden om innehållet (t ex måste ni kunna hantera ett okänt antal personer/kunder) December 1, 2013 17
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons()); 18
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); Vi skapar en klass PersonFromFile, if (personarray.length den == 3){ är publik och innehåller endast en mainmetod. (Vi behöver även tala om vilket Person p = new Person(personarray[0], int fodelse = Integer.parseInt(personarray[2]); paket klassen ligger i och importera de personarray[1],fodelse); klasser vi behöver anävnda i main-system.out.println("skapametoden, syns inte här. person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons()); 19
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); Vi skapar ett File-objekt, som s = br.readline(); representerar filen alt1.txt (som ligger i vår projektkatalog) sedan försöker vi br.close(); skapa en FileReader och en catch (Exception e){ BufferedReader som använder den (kan e.printstacktrace(); kasta undantag om filen inte finns). Går det bra så läser vi in första raden i filen. System.out.println("Antal personer = " + Person.getNoOfPersons()); 20
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); Vi vill läsa in alla data i hela filen, så vi s = br.readline(); har en loop som säger att vi ska fortsätta tills vi inte längre har några br.close(); rader att läsa in, dvs vi får tillbaka null catch (Exception e){ av vår BufferedReader. e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons()); 21
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); För varje inläst rad gör vi följande: Dela upp raden i br.close(); sin "beståndsdelar", dvs dela catch strängen (Exception vid varje e){ kommatecken. Resultatet e.printstacktrace(); hamnar i en array av strängar. Vi vet hur formatet på filen ska System.out.println("Antal se ut, så vi vet att längden personer på = " + Person.getNoOfPersons()); arrayen borde vara 3, men kolla för säkerhets skull... 22
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline();...gör om den tredje delsträngen till ett heltal (vi vet att br.close(); årtalet ska vara ett tal och inte catch en textsträng (Exception e){ när vi skapar vår Person-instans). e.printstacktrace(); Skapa sedan en ny instans (new) av klassen System.out.println("Antal Person, genom att anropa personer = " + Person.getNoOfPersons()); konstruktorn, och lagra resultatet i variabeln p... 23
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); p String s = br.readline(); while (s = null){ String[] personarray = s.split(","); Person if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline();...gör om den tredje delsträngen till ett heltal (vi vet att br.close(); årtalet ska vara ett tal och inte catch en textsträng (Exception e){ när vi skapar vår Person-instans). e.printstacktrace(); Skapa sedan en ny instans (new) av klassen System.out.println("Antal Person, genom att anropa personer = " + Person.getNoOfPersons()); konstruktorn, och lagra resultatet i variabeln p... 24 Anna
Person public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; public static int getnoofpersons(){ return noofpersons; public String getname (){ return fname + " " + lname; public void setlastname (String newname){ lname = newname; 25
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons());...skriv sedan ut namnet på personen genom att anropa metoden getname() på den specifika instansen av Person som finns lagrad i varaibeln p. 26
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer Sen = läser " + Person.getNoOfPersons()); vi in nästa rad och fortsätter loopen... 27
public class PersonFromFile { Arvid public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ Detta varv har vi en ny sträng att hantera. Vi delar upp den br.close(); på samma catch (Exception e){ sätt, och skapar en ny Person-instans e.printstacktrace(); som vi lagrar i varaibeln p och sedan skriver ut. s = br.readline(); int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); System.out.println("Antal personer = " + Person.getNoOfPersons()); Kom ihåg att konstruktorn även räknar antalet instanser och lagrar det i en klassvariabel... p Person 28
Person public class Person { //Klassvariabel private static int noofpersons = 0; //Instansvariabler private String fname; private String lname; private int year; public Person(String fn, String ln, int yr){ fname = fn; lname = ln; year = yr; noofpersons++; public static int getnoofpersons(){ return noofpersons; public String getname (){ return fname + " " + lname; public void setlastname (String newname){ lname = newname; 29
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer Sen = läser " + Person.getNoOfPersons()); vi in nästa rad, men nu kommer vi få tillbaka null, vi har nått EOF... 30
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); System.out.println("Skapat person: " + p.getname()); s = br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer Vi stänger = " + Person.getNoOfPersons()); strömmen... 31
public class PersonFromFile { public static void main(string[] args) { File personfil = new File("alt1.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String s = br.readline(); while (s = null){ String[] personarray = s.split(","); if (personarray.length == 3){ int fodelse = Integer.parseInt(personarray[2]); Person p = new Person(personarray[0], personarray[1],fodelse); Och avslutar med att skriva ut värdet på System.out.println("Skapat person: " + p.getname()); klassvariabeln noofpersons från Person-klassen. Den är private, så vi får s = br.readline(); använda en get-metod för att komma åt den br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons()); 32
public class PersonFromFile2 { public static void main(string[] args) { File personfil = new File("alt2.txt"); try { FileReader fr = new FileReader(personfil); BufferedReader br = new BufferedReader(fr); String fornamn=br.readline(); while (fornamn = null){ String enamn = br.readline(); int fodelse = Integer.parseInt(br.readLine()); Person p = new Person(fornamn,enamn,fodelse); System.out.println("Skapat person: " + p.getname()); fornamn=br.readline(); br.close(); catch (Exception e){ e.printstacktrace(); System.out.println("Antal personer = " + Person.getNoOfPersons()); 33
Reguljära uttryck (överkurs) OBS Överkurs - men kan vara bra att ha t ex till projektet - läs igenom på egen hand December 1, 2013 34
Vad är ett reguljärt uttryck? Ett sätt att beskriva en mängd av textsträngar Ett sätt att beskriva ett "mönster" som textsträngar kan uppfylla Används ofta för att söka efter strängar, eller manipulera dem q q q Exempel: hitta alla textsträngar som innehåller bokstavssekvensen "abc" Exempel: byt ut alla förekomster av sekvensen "abc" mot bokstaven "d" Används när ni anropar s.split(","); -, är ett reguljärt uttryck Olika syntax i olika programmeringsspråk och gänssnitt men samma principer - här: Java-syntax December 1, 2013 35
Grundprincipen Ett tecken matchar sig självt q Exempel: det reguljära uttrycket a matchar index 0 och 2 i textsträngen apa q Exempel: det reguljära uttrycket ap matchar index 0-1, 3-4 och 6-7 i textsträngen apaapaapa q, matchar sig självt när vi ska dela upp strängen mha split() Men... om vi i vår Java-kod frågar om a matchar apa kommer svaret vara false - apa innehåller mer än bara ett enda a December 1, 2013 36
Operatorer... Konkatenering Alternativ Teckenklasser "Jokertecken" Upprepning I Java finns följande reserverade tecken för reguljära uttryck: < ( [ { \ ^ - = $ ] )? * +. > q Om man vill matcha tecknet självt används \ framför som "escape character" - Exempel: \? matchar strängen? December 1, 2013 37
Operatorer - översikt Konkatenering q det reguljära uttrycket ap matchar index 0-1, 3-4 och 6-7 i textsträngen apaapaapa - ap är konkateneringen av a och p Alternativ - q det reguljära uttrycket a p matchar antingen strängen a eller strängen p Teckenklasser = beskriver en mängd av tecken q Omgärdas av [ ] q q [abc] - matchar någon av bokstäverna a, b eller c [a-za-z] - matchar en (stor eller liten) bokstav i engelska alfabetet December 1, 2013 38
Operatorer - översikt Jokertecken q. matchar vilket tecken som helst Upprepning q q q? - 0-1 gång, exempel: a? = matchar tecknet a eller inget tecken alls * - 0-många gånger, exempel: a* = matchar inget tecken alls, eller tecknet a en eller flera gånger i rad + - 1-många gånger, exempel: a+ = matchar tecknet a en eller flera gånger i rad December 1, 2013 39
Exempel [a-za-z]*a matchar alla strängar som bara innehåller bokstäver i engelska alfabetet och avslutas med ett litet a [0-9][0-9] matchar alla heltal (uttryckta som en textsträng) med två siffror, dvs tal från 00 till 99 ; matchar ett semikolon, ;+ matchar ett eller flera semikolon i rad.[a-za-z]. matchar alla strängar med tre tecken där det mittersta tecknet är en bokstav i engelska alfabetet Från tidigare: s.split(","); q q Dela textsträngen runt den delsträng som matchar uttrycket, dvs "dela textsträngen runt alla kommatecken" Vi skulle kunna blanda separatorer: s.split(", ;"); December 1, 2013 40
Sammanfattning Att skapa en klass q q Klassens beståndsdelar Exempel: Person Repetition: modifierare Att skapa instanser av en klass q Exempel som läser in data från fil och skapar instanser December 1, 2013 41
December 1, 2013 42