Laboration 2 Objektorienterad programmering i Java I Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6 Syfte: Att kunna använda sig av olika villkors- och kontrollflödeskonstruktioner i sitt program. Att kunna jämföra strängar med varandra Redovisning: Samtliga uppgifter ska redovisas under ordinarie laborationstid för någon av handledarna. Därefter ska alla filer skickas in via mail till kursansvarig. Lycka till!
Uppgift 1 Översikt Uppgiften i denna del går ut på att skapa en enkel klass som klarar av att utföra de fem grundläggande aritmetiska operationerna (addition, subtraktion, multiplikation, division och modulus). Syftet med laborationen är att stifta bekantskap med uttrycket String[] args i main() metoden, hur konvertering av strängar till tal fungerar, samt hur man använder sig av if-satser. Uppgift Du ska skapa en klass vars uppgift är att utföra de fem olika räknesätten på två tal av typen double. Det speciella med klassen är att den enbart ska innehålla statiska metoder (s.k. klassmetoder), vilket innebär att vi inte behöver skapa ett objekt av klassen för att utföra en beräkning. En beräkning ska kunna utföras på två olika sätt. All information, d.v.s. vilket räknesätt som ska utföras och vilka talen är, kan antingen anges som argument till applikationen när denna startas eller så används någon av de statiska metoderna (se UML nedan). Första parametern op1 innehåller första talet, andra parametern op innehåller räknesättet, och sista parametern op2 innehåller det andra talet. Calc + calculate(op1 : String, op : String, op2 : String) + calculate(op1 : double, op : String, op2 : double) + main(args : String[]) Oavsett vilket sätt som används ska det kontrolleras vilket det aktuella räknesättet är och därefter utföra räknesättet på de två talen. En kontroll ska göras innan själva beräkningen så att det är ett giltigt räknesätt som används. Efter att beräkningen är utförd ska resultatet skrivas ut och därefter har programmet exekverat färdigt. För att utföra en beräkning kan man alltså använda något av följande tre sätt: java Calc 3.1 + 4.9 Calc.calculate("3.1", "+", "4.9"); Calc.calculate(3.1, "+", 4.9); varpå utskriften kan se ut så här: 3.1 + 4.9 = 8.0 Det första alternativet startas t.ex. från en DOS-prompt där talen och det räknesätt som ska användas skickas som argument till applikationen. I main()måste en kontroll utföras så att rätt antal argument har angetts innan beräkningen kan utföras. - 1 -
Det andra alternativet anropas t.ex. från ett annat objekt som vill utför en beräkning. Som argument till metoden skickas tre strängar där det andra argumentet anger vilket räknesätt som ska användas. Det första och tredje argumentet anger de tal på vilket räknesättet ska utföras. En kontroll måste utföras så inte ett ogiltigt räknesätt används, samt att strängarna som innehåller talen måste konverteras till rätt datatyp. Det tredje alternativet anropas på samma sätt som det andra, men med den skillnaden att talen som skickas är av typen double. Tips För att kontrollera hur många argument som angetts när applikationen startas kan du skriva args.length som returnerar ett heltal med antalet argument. De olika argumenten kommer du åt genom att skriva args[0] för första argumentet, args[1] för andra argumentet osv. Observera att om endast ett argument angetts genereras ett fel om vi använder args[1]. För att konvertera en sträng till t.ex. en double måste du använda dig av wrapper-klassen Double. Exempel: String s = "3.14"; double d = Double.parseDouble(s); För att jämföra en sträng med en annan sträng anropar du metoden equals() på ett av sträng objekten. Exempel: String s = "hej"; if (s.equals("hej")) { // Strängarna är lika } else { // Strängarna inte är lika } Det är fel att jämföra strängar genom att använda ==. Upprepa inte koden för att kontrollera räknesätt m.m. i samtliga metoder som ska utföra en beräkning utan det räcker att en metod gör detta. De övriga metoderna kan utföra nödvändiga konverteringar m.m. och sen anropa den metod som verkligen utför beräkningen. Anser du att fler metoder är nödvändiga, än de som visas i UML-diagrammet, är det helt ok att lägga till fler. Använd nyckelordet return om du har behov att avbryta exekveringen av en metod innan metoden är slut. Av någon anledning, varför har jag inte lyckats klura ut, så fungerar det inte att skriva * för multiplikation när vi startar applikationen från DOS-prompten. Använd därför i stället bokstaven x för multiplikation. Görs däremot ett anrop direkt på någon av metoderna calculate()går det bra att använda *. - 2 -
Krav För att uppgiften skall betraktas som godkänd krävs följande: Applikationen ska kunna beräkna både heltal och decimaltal. Skrivs fel antal argument in (fler eller färre än 3) när applikationen startas från DOS-prompten ska en text skrivas ut som förklarar hur argumenten används. Anges ett icke tillåtet räknesätt ska detta meddelas samt att giltiga räknesätt visas. Både bokstaven x och * ska vara giltiga räknesätt för multiplikation. Görs ett försök att dividera ett tal med 0 (noll) ska ett felmeddelande skrivas ut och ingen beräkning utföras. Alla skärmutskrifter skall vara välstrukturerade och lätta att förstå (se bilden nedan för exempel på utskrifter). En kontroll som kollar att det verkligen är siffror som skrivits behöver inte utföras eftersom vi inte behandlar felhantering i denna kurs. Kommentera rikligt i källkoden och beskriv vad som händer (inga dokumentationskommentarer krävs). När du anser dig vara färdig med uppgiften så visar du din laboration för handledaren, eller så börjar du med nästa uppgift. - 3 -
Uppgift 2 Översikt Uppgiften i denna del går ut på att skapa en klass som ska simulera en enkel kommandotolk, d.v.s. den läser in kommandon från användaren och tolkar dessa. Syftet med laborationen är att stifta bekantskap med olika kontrollflödeskonstruktioner, hur man jämför strängar med varandra, samt hur strängar läses in från tangentbordet. Uppgift Skapa en klass vars uppgift är att simulera en enkel kommandotolk som läser in kommandon från användaren och sedan utför dessa. Kommandon från användaren ska läsas in från tangentbordet. Applikationen är tänkt att fungera på liknande sätt som DOS-promten (Win98) och CommandPrompt (Win2000, NT4) där vi kan skriva kommandon för att t.ex. kompilera javakod (javac) eller lista filer i en katalog (dir). När applikationen startas ska en prompt skrivas ut (t.ex. kommando>) varpå användaren får skriva in ett kommando. Prompten är enbart en text som skrivs ut i väntan på att användaren ska skriva in ett kommando. T.ex. i CommandPrompt motsvarar prompten den katalog vi för närvarande befinner oss i. Det kan t.ex. vara H:\java\lab2> eller C:\>. Det kommando som skrivs in ska sedan applikationen tolka och utföra. Om ett felaktigt kommando anges ska ett felmeddelande, samt de kommandon som kan tolkas skrivas ut. Efter att kommandot utförts ska prompten återigen visas och ett nytt kommando kan anges. Detta upprepas ända till kommandot för att avsluta anges. De kommandon som ska kunna tolkas är: help skriver ut en hjälptext liknande denna q avslutar quit samma som q hello Skriver ut texten HelloWorld! prompt byter prompt udda avgör om ett tal är udda eller inte upprepa skriver ut en valfri mening x antal gånger calc utför en enkel matematisk beräkning calculate samma som calc När applikationen startas ska man kunna ange den prompt som ska användas. Detta görs genom att skicka prompten som ett argument till applikationen. Startas applikationen utan argument ska en default-prompt användas i stället. Med andra ord ska det vara möjligt att skapa objekt av klassen på två olika sätt. Se förslag på design till höger (fler medlemmar får/ska läggas till). CommandPrompt - prompt : String + CommandPrompt(prompt : String) + CommandPrompt() + starta() + main(args : String[]) På det skapade objektet anropas metoden starta() som skriver ut prompten och väntar på att användaren ska skriva in ett kommando. - 4 -
Tips Krav Glöm inte att importera rätt klass för att kunna läsa in rader. Glöm heller inte att kasta vidare eventuella fel, som kan uppstå när man läser en rad från tangentbordet. Måste ske i alla metoder där man läser in rader. Deklarera objektet, som läser in från tangentbordet, på rätt ställe i klassen så att objektet kan användas i hela klassen (som ett fält?). Använd någon form av loop i metoden starta() för inläsning av kommando samt tolkningen av detta. För att avsluta exekveringen någonstans i koden används System.exit(0); help ska skriva ut en hjälptext över vilka kommandon som kan tolkas och vad varje kommando gör. q eller quit ska avsluta programmet. hello ska skriva ut texten HelloWorld! på skärmen. prompt ska fråga användaren efter en textsträng och därefter använda den som ny prompt istället för den gamla. udda ska fråga användaren efter ett heltal och kontrollera om talet är udda eller jämt. En utskrift som tydligt visar om talet är jämt eller udda ska utföras. upprepa ska fråga användaren efter ett heltal och en textsträng. Därefter ska denna textsträng skrivas ut lika många gånger som heltalet som efterfrågades. calc eller calculate ska fråga användaren efter två tal och ett räknesätt. Därefter ska denna beräkning utföras med klassen Calc i föregående uppgift. Alla kommandon ska utföras i egna metoder, d.v.s. det ska finnas en metod som hanterar kommandot hello, en för udda, en för upprepa, e.t.c. Alla skärmutskrifter skall vara välstrukturerade och lätta att förstå (se exempel på utskrifter nedan). När du anser dig vara färdig med uppgiften så visar du din laboration för handledaren. - 5 -