• No results found

LÖSNINGSFÖRSLAG TENTAMEN

N/A
N/A
Protected

Academic year: 2022

Share "LÖSNINGSFÖRSLAG TENTAMEN"

Copied!
8
0
0

Loading.... (view fulltext now)

Full text

(1)

L ÖSNINGSFÖRSLAG – T ENTAMEN

O

BJEKTORIENTERAD PROGRAMMERING I

J

AVA

5

P FRISTÅENDE KURS, KVÄLL (ITM - ÖSTERSUND)

LÖRDAG 18 JANUARI, 2003, KL. 9 - 14 TID: 5 TIMMAR

ANTAL UPPGIFTER: 9 MAX POÄNG: 45 BETYGSKALA:

UNDERKÄND 3 4 5

0 - 20 21 – 29 30 - 38 39- 45

ANVISNINGAR:

• INGA HJÄLPMEDEL TILLÅTNA (EGEN RÄKNARE OCH LINJAL ÄR OK)

• ALL KOD DU SKRIVER SKA VARA LÄTTLÄST OCH INDENTERAD

• KOMMENTERA KODEN VID BEHOV

• SKRIV ENDAST EN UPPGIFT PÅ VARJE BLAD

• SKRIV EJ PÅ BAKSIDAN AV BLADET

• BÖRJA MED ATT LÄSA IGENOM ALLA UPPGIFTER

• KURSANSVARIG KOMMER CA 10.00 FÖR ATT SVARA PÅ EVENTUELLA FRÅGOR

LYCKA TILL!

(2)

Uppgift 1 (8p) a) 5p

Förklara innebörden av nedanstående klassdeklaration. Vad betyder varje enskilt nyckelord (markerade med fetstil)?

public final class JavaTenta extends Tenta implements Rättningsbar

SVAR: Vi deklarerar en publik klass med namnet JavaTenta. Denna klass ärver sina egenskaper från klassen Tenta samtidigt som den implementerar gränssnittet Rättningsbar. Klassen kan inte ärvas eftersom den är deklarerad att vara final.

b) 2p

Nedanstående programsatser genererar ett fel vid kompilering. Varför då?

Ändra eller lägg till rader så att värdet i variabeln d lagras i variabeln i.

double d = 1000000000; // En miljard int i = d;

SVAR: Vi får ett felmeddelande liknande ’possible loss of precision’. Detta eftersom vi försöker tilldela värdet av en double (64 bitar) till en variabel av typen int (32 bitar). Sådana konverteringar går inte att göra automatiskt (implicit typkonvertering) utan vi måste tvinga fram en konvertering (explicit typkonvertering). Följande kod löser problemet:

double d = 1000000000; // En miljard int i = (int)d;

c) 1p

Vad används nyckelordet instanceof till? Ge gärna exempel på användning.

SVAR: Med instanceof kan vi testa av vilken typ (klass) ett objekt är av.

Kan vara nödvändigt att göra när vi ska konvertera mellan olika typer. T.ex när vi plockar ut element från en Vector om denna innehåller fler än en typ av objekt.

Uppgift 2 (2p)

Hur överförs parametervärden i Java (värden som skickas till en metod) och vad innebär det? Förklara även vad skillnaden blir mellan primitiva typer och objekt?

SVAR: Parametrar/variabler överförs med s.k. värdeanrop (”call by value”), vilket innebär att det är en kopia av parametern som skickas. Använder vi primitiva typer som parametrar påverkas inte den variabel som metoden anropades med. D.v.s. värdet på ”kopian” är skiljd från värdet på ”originalet”.

Använder vi däremot ett objekt som parameter så är det en kopia på objektreferensen som skickas. Denna kopia refererar till samma objekt som originalet och därför påverkar eventuella förändringar i kopian även originalet (t.ex. om vi anropar en metod för att ändra värdet på ett av objektets data).

(3)

Följande skrivs ut på skärmen:

8 10.0 31.0

i2 + i1 = 101 true

false false abc

Rad1: Här utförs heltalsdivision mellan 10 och 4 vilket är 2. Multipliceras sen med 4.

Rad2: Här utförs vanlig division. Kom ihåg att allt konverteras till double först, vilket innebär att vi vid utskriften får med en decimal del.

Rad3: Börja med den inre parentesen där vi dividerar 2 med 2.0, vilket är 1.0. Detta adderas med 10.0, vilket blir 11.0. ++i1 innebär öka först värdet på i1 och använd det sen. Därför multipliceras 1.0 med 11.0 (värdet inom parentesen). Från produkten av detta, som är 11.0, ska vi dra ifrån i2 * -d1. Detta översätts till 10 * -2.0, vilket är –20.

Tillsist får vi då 11.0 - -20. Och minus minus blir plus så resultatet är 31.0

Rad4: Här är det strängaddition som utförs! Viktigt att komma ihåg att värdet på i1 har ökats med 1!

Rad5: Här är det logiskt-eller som ska utföras. Första operanden är i2 < d2, vilket är 10 < 2.0, vilket är falskt. Andra operanden är !b2, vilket är !false, vilket är sant. Dvs till slut kollar vi: falskt eller sant, vilket är sant (true).

Rad6: Här utförs en mängd med jämförelser med och-operatorn. b1 && b1 && !b2

&& b2 är detsamma som sant && sant && !falskt && falskt. I och med att vi på slutet har värdet falskt så får hela uttrycket värdet falskt (false). && kräver att operanderna ska vara sann för att uttrycket ska vara sant.

Rad7: Måste börja med den inre parentesen där vi kollar om sant && i2-d2==0. i2 och d2 har värdet 10 så 10 minus 10 är ju 0 och uttrycket är då sant. Sant && sant är i sin tur sant så uttrycket inom parentesen får värdet true. Men i och med att vi har icke- operatorn framför parentesen blir uttrycket false. Detta använder vi sen i en eller- operator där andra operanden är d2 != 10. Värdet 10 är ju inte skiljt från 10 så detta resulterar i falskt. Falskt eller falskt i sin tur är falskt så utskriften blir false.

Rad8: Villkorsoperatorn! Funkar som så att om uttrycket framför ? är sant så används det som står mellan ? och : annars används värdet som står efter :. I det är fallet är uttrycket sant så därför används ”abc” i utskriften.

Uppgift 4 (2p)

Skriv en metod med namnet boolToString som tar en boolean som parameter och returnerar värdet på den som en sträng. T.ex., boolToString(true) returnerar strängen "true".

public String boolToString(boolean b) {

if (b)

return "true";

return "false";

}

(4)

Uppgift 5 (4p)

Följande skrivs ut på skärmen:

01246789 102

SVAR: Vi har en for-loop där vi sätter loopvariabeln i till 0. Denna loop ska snurra så länge som i > -1. Dvs vi har en oändlig loop eftersom i alltid kommer att vara 0 eller större. Första varvet i loopen kommer i att vara 0 och det första som händer är att vi kollar om i < 10, vilket är sant. Därför kollar vi nu om i == 3 eller om i == 5. i är varken 3 eller 5 så därför körs inte raden med continue. Istället görs en utskrift av i (som är 0) på skärmen. OBS vi använder inte println, dvs ingen radbrytning sker.

Så här snurrar det nu på så länge som i < 10, men nu i är 3 eller när i är 5 så kommer raden med continue att exekveras, vilket gör att resterande del av loopen skippas. Det blir med andra ord ingen utskrift på skärmen för 3 eller 5.

När i inte längre är mindre än 10 så kollar vi om i är större än 100. Dvs när i == 101 så kommer koden i else-if att köras. Där ökas i på med 1 till 102 och som därefter skrivs ut på skärmen, men på en ny rad (”\n”).

Uppgift 6 (5p)

Skriv en metod med namnet initialer som skriver ut en persons initialer. Metoden tar en array av typen String som parameter. Denna array innehåller ett antal för- och efternamn enligt formatet: efternamnet följt av mellanslag följt av förnamnet.

public void initialer(String[] namn) {

// Vi loopar igenom alla namn i arrayen for (int i = 0; i < namn.length; i++) {

// Börjar med att konvertera till STORA bokstäver String namnet = namn[i].toUpperCase();

// För att få reda på var första bokstaven i // förnamnet finns letar vi efter mellanslaget int mellanslag = namnet.indexOf(' ');

// Förstabokstaven i förnamnet finns nu på position mellanslag // +1 och första bokstaven i efternamnet finns på position 0.

char f = namnet.charAt(mellanslag +1 );

char e = namnet.charAt(0);

// Vi skriver ut bokstav för bokstav System.out.print(f);

System.out.println(e);

// Det vore fel att skriva så här: System.out.println(f + e);

// Eftersom detta adderar acsii-värdet i f och e med // varandra innan utskriften görs. Om man däremot adderar // en tom sträng "" så utförs strängaddition.

// System.out.println("" + f + e);

}

(5)

Uppgift 7 (4p)

Följande skrivs ut på skärmen:

Konstruktorn i Uppgift7_2 Konstruktorn i Uppgift7_1 Konstruktorn i Uppgift7 Uppgift7_2

SVAR: Här är det frågan om arv mellan klasser där det gäller att hålla reda på i vilken ordning konstruktorer och metoder anropas. Det var klassen Uppgift7 som skulle köras och vi tittar därför i dess main-metod. Där skapas ett nytt objekt av klassen och vi skickar strängen ”Konstruktorn i” som parameter till klassens konstruktor.

Det första som sker där är ett anrop med super, till superklassens konstruktor. I klassdeklarationen ser vi att det är klassen Uppgift 7_1 som är superklassen. Vi skickar vidare strängen.

Konstruktorn i klassen Uppgift7_1 tar emot strängen men skickar den direkt vidare till sin superklass, som är Uppgift7_2. I klassen Uppgift7_2’s konstruktor gör vi en utskrift av strängen s + ” ” + klass. Dvs ”Konstruktorn i Uppgift7_2” skrivs ut.

Därefter återgår exekveringen till raden efter super-anropet i klassen Uppgift7_1 där samma utskrift sker, men nu är det innehållet i Uppgift7_1’s fält klass som skrivs ut.

Utskriften blir därför ”Konstruktorn i Uppgift7_1”.

Samma typ av utskrift sker sen i konstruktorn i Uppgift7, men innehållet i klass är

”Uppgift7” så därför skrivs ”Konstruktorn i Uppgift7” ut.

Efter den utskriften anropas metoden fundering och där vi skickar med fältet klass som parameter, dvs vi skickar strängen ”Uppgift7”. Det som returneras av detta metodanrop lagrar vi i objektet svar.

Klassen Uppgift7 har ingen egen fundering-metod så därför används den som ärvdes från klassen Uppgift7_1. I den metoden görs ett anrop till superklassens fundering- metod och vi skickar vidare strängen ”Uppgift7”.

Metoden fundering i Uppgift7_2 tar emot parameter och lagrar den i klass. Men det som returneras är this.klass, dvs fältet klass och intemetodens lokala klass. Så det som returneras tillbaka och lagras i objektet svar är strängen ”Uppgift7_2”. Och denna sträng skrivs ut på skärmen varpå applikationen har exekverat klart.

Uppgift 8 (10p) a) (6p)

Skriv en klass Kapitel som representerar ett kapitel i en bok. Klassen ska innehålla uppgifter om numret på kapitlet, rubriken på kapitlet, antal sidor och texten. Det ska finnas metoder för att sätta och hämta data om klassen samt en metod med namnet info, som skriver ut information om kapitlet enligt formatet:

kapitel, rubrik – antalSidor (ex. med data ovan: "2, Olyckan – 55")

(6)

public class Kapitel {

private int kapitel; // Vilket kapitel private String rubrik; // Rubrik på kapitlet

private int antalSidor; // Antalet sidor kapitlet har private String text; // Texten i kapitlel

// Klassens konstruktor

public Kapitel(int kapitel, String rubrik, int antal, String text) {

this.kapitel = kapitel;

this.rubrik = rubrik;

this.antalSidor = antal;

this.text = text;

}

// Metoder för att sätta data

public void setKapitel(int kapitel) { this.kapitel = kapitel;

}

public void setRubrik(String rubrik) { this.rubrik = rubrik;

}

public void setAntalSidor(int antalSidor) { this.antalSidor = antalSidor;

}

public void setText(String text) { this.text = text;

}

// Metoder för att returnera data public int getKapitel()

{

return kapitel;

}

public String getRubrik() {

return rubrik;

}

public int getAntalSidor() {

return antalSidor;

}

public String getText() {

return text;

}

// Metod som returnerar information om kapitlet public String info()

{

return kapitel + ", " + rubrik + " - " + antalSidor;

} }

b) (4p)

Skriv en testklass som du döper du till KapitelTest. I denna testklass skapar du ett objekt av klassen Kapitel med lämpliga värden på fälten och demonstrerar sen alla metoder i denna klass enligt:

(7)

2. Ändra namn på rubriken

3. Skriv ut det den ny rubriken på skärmen

public class KapitelTest {

public static void main(String[] args) {

// Skapar ett objekt av klassen Kapitel

Kapitel k = new Kapitel(2, "Olykan", 55, "Innan Ola visste "

+ " vad som hade hänt var olyckan redan ett faktum.");

// Skriver ut information om kapitlet på skärmen System.out.println(k.info());

// Sätter ny rubrik på kapitlet k.setRubrik("Olyckan");

// Skriver ut den nya rubriken på skärmen System.out.println(k.getRubrik());

} }

Uppgift 9 (6p)

I denna uppgift ska du utgå från den klass du skrev (eller skulle skriva) i uppgift 8 samt den givna klassen Bok. Klassen bok saknar konstruktorn och metoderna

visaInnehallsforteckning samt toString. Din uppgift är att skriva denna konstruktor samt de två metoderna.

Konstruktorn ska ta två parametrar där den första innehåller bokens titel (String) och den andra innehåller antalet kapitel boken har (int). Förutom tilldelning av fält ska konstruktorn även skapa den vector (kapitel) som innehåller bokens alla kapitel.

Vectorn ska vara tillräckligt stor för att rymma alla kapitel.

// Klassens konstruktor

public Bok(String titel, int antalKapitel) {

this.titel = titel;

// Skpara Vectorn 'kapitel' så att kapaciteten blir // densamma som antalet kapitel boken har.

kapitel = new Vector(antalKapitel);

}

forts på nästa sida…

(8)

Metoden visaInnehallsforteckning ska skriva ut en innehållsförteckning för boken på skärmen. Metoden ska utnyttja metoden info som finns i klassen Kapitel (se uppgift 8a). Ingen hänsyn behöver tas så att kapitlen skrivs ut i nummerordning.

// Visar en innehållsförteckning för boken public void visaInnehallsforteckning() {

// Vi loopar igenom alla kapitel, dvs alla element i Vectorn for (int i = 0; i < kapitel.size(); i++)

{

// Plockar ut elementen i Vectorn (som ett Object) Object o = kapitel.elementAt(i);

// Konverterar till ett objekt av klassen Kapitel Kapitel k = (Kapitel)o;

// Anropar metoden info() och skriver ut på skärmen System.out.println(k.info());

} }

Metoden toString ska returnera en strängrepresentation av aktuellt Bok-objekt. Den sträng som returneras ska ha formatet:

Boken ’titel’ har ’totalt_antal_sidor’ sidor

(Ex: Boken Java har 1143 sidor)

I metoden ska bokens totala antal sidor beräknas fram. För att beräkna detta måste metoder i klassen Kapitel utnyttjas.

// Returnerar en strängrepresentation av boken public String toString()

{

// Sätter antalet sidor till 0 int antal = 0;

// Loopar igenom alla element i Vectorn for (int i = 0; i < kapitel.size(); i++) {

// Plockar ut och konverterar elementen i Vectorn Kapitel k = (Kapitel)kapitel.elementAt(i);

// Anropar metoden getAntalSidor() för varje kapitel antal = antal + k.getAntalSidor();

}

// Returnerar en sträng enligt rätt format

return "Boken " + titel + " har " + antal + " sidor";

}

References

Related documents

- Jag tror att de vinnande anbudsgivarna kommer lyckas bra med att utforma området i och kring Gläntan till ett attraktivt och levande bostadsområde på ett sätt som värnar om

Kostnaden f¨or denna nya variabel beror dock p˚ a hur mycket av de olika exklusiva r˚ avarorna vi v¨aljer att ha med p˚ a pizzan.. Ny variabel, vi kan anv¨anda formeln ¯ c ny = c

(I origo kan vi inte anv¨anda gradienterna f¨or att hitta en normalvektor eftersom gradienterna ¨ar noll. Detta ¨ar tv˚a par av linjer, men de ¨ar orienterade med en vinkel π/4

Vi vill visa att h¨ogerledet minus v¨ansterledet

[r]

spänningarna över komponenterna.. Det leder till samma resultat, men blir lite mer att räkna.. Alltså kan sysemet H inte vara tidsinvariant. c) Det räcker inte med att observera

Utan att g˚a in p˚a kombinatorik kan vi helt enkelt r¨akna upp de m ¨ojliga funktionerna, genom att betrakta m ¨ojliga v¨arden p˚a y 0 ,... Vi visar detta med hj¨alp

Best¨am den st¨orsta arean man kan f˚a av en rektangel som kan beskrivas s˚a att varje sida g˚ar genom var sitt h¨orn av en annan rektangel med sidl¨angderna a och