Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag 00 - juni - 17 Tentamen i Objektorientering och Java Skrivtid 5 h Antalet uppgifter : 4 (12p+8p+12p+8p = 40p) Lärare, jourhavande lärare : Leif Kusoffsky ------------------------------------------------------------------------------------------------------------------ Tillåtna hjälpmedel: Läroboken: Ericsson : Programutveckling med Java. ----------------------------------------------------------------------------------------------------------------- 1 Städer har alltid ett namn och ett visst antal innevånare. Vissa städer (t ex Umeå och Nyköping) är residensstäder och har då en landshövding, andra städer (t ex Strängnäs, Lund och Skara) är stiftsstäder och har en biskop. a) Antag tills vidare (uppgift 1 a) till 1 f))att inga städer kan vara kombinerade stifts- och residensstäder. Modelera i Java med tre klasser denna situation, som den dessutom beskrivs med nedanstående UML-liknade klassdiagram. De tre klasserna som skall skrivas skall dessutom ha lämpliga konstruerare som initierar attributen. Stad int inv String namn String vilketnamn() int antalinnevånare() Residensstad String landshövding String vemärlandshövding() Stiftsstad String biskop String vemärbiskop() b) Klassen Stad är inte abstrakt. Varför? c) Antag att vi i en Java-klass har en deklaration Stad [] stad; och att stad refererar till ett arrayobjekt som innehåller uppgifter om städer av olika slag. Hur skriver man i klassen en metod som skriver ut (på System.out) uppgifterna om städerna? För alla städer skall namn och innevånarantal anges, i förkommande fall även namn på landshövding och biskop. Uppgiften skall lösas enbart med de metoder som finns i klassdiagrammet. (Jämför även uppgift1 c) och 1d))
d) I uppgift c) tvingades vi kontrollera vilken sorts stad som vi skulle skriva ut information om. Detta anses inte som bra OO-programmering. Varför? e) En bättre lösning är att alla de tre klasserna i klassdiagrammet förses med en metod String info() som retunerar lämplig information för de olika städerna. Skriv metoden för de tre klasserna. Skriv också en ny lösning på uppgiften i c), som nu kan lösas på "OO-sätt". f) Fyll arrayen stad i uppgift 1c med en vanlig stad, en stiftsstad och en residensstad. (t ex Örnsköldsvik med 56658 innevånare, Lund med 97975 innevånare och biskopen Cristina Odelberg, Umeå med 103517 innevånare och landshövdingen Georg Andersson) g) "Metropoler" (som t. ex Stockholm och Luleå) är både stifts- och residensstäder. I många OO-språk kan detta modelleras med en ny fjärde klass StiftsOchResidensstad som ärver både Stiftsstad och Residensstad. Detta kan man inte göra i Java. Hur kan man göra istället? För full poäng skall det finnas ett begrepp som kan användas som typnamn för residensstäder, vare sig de är enbart residensstäder eller "metropoler", och ett begrepp som kan användas som typnamn för stiftsstäder, vare sig de är enbart stiftsstäder eller "metropoler". Denna deluppgift är nog den svåraste uppgiften i denna tentamen.
2. Vad skrivs ut om detta program körs (OBS ibland twice, iblad twiced)? public class RefMM { public static void main(string [] argv ) { int i = 10; int j = 11; System.out.println("i = " + i + " j = twiced(i); System.out.println("i = " + i + " i = 10; j = 11; System.out.println("i = " + i + " twice(i); System.out.println("i = " + i + " j = " + j); j = " + j); j = " + j); j = " + j); int [] a = new int [2]; a[0] = 11; a[1] = 12; int [] b = new int [2]; b[0] = 15; b[1] = 9; System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); b = twicedarr(a); System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); a[0] = 11; a[1] = 12; b[0] = 15; b[1] = 9; System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); twicearr(a); System.out.print( "a ={" + a[0] + "," + a[1] + ""); System.out.println(" b ={" + b[0] + "," + b[1] + ""); private static int twiced(int ii) { return ii *ii; private static void twice(int ii) { ii = ii *ii; private static int [] twicedarr(int [] ia) { int [] result = new int [ia.length]; for (int k = 0; k < ia.length; k = k+1) { result[k] = ia[k]*ia[k]; return result; private static void twicearr(int [] ia) { for (int k = 0; k < ia.length; k = k+1) { ia[k] = ia[k]*ia[k];
3. En räknare (Counter) är ett don med två knappar och ett textfönster samt ett internt minne för ett heltal.textfönstret visar minnets innehåll. Knappen Reset nollställer minnet, knappen OneMore ökar minnets innehåll med ett. I uppgift 3 b) finns en bild av två räknare. a) Skriv med hjälp av Javas awt.paket en klass Counter. Klassen skall innehålla en konstruerare som gör att man får en bild (en Frame) av en datoriserad räknare när man instansierar ett Counter-objekt. Konstrueraren skall ha parametrar som betämmer bildens storlek och titel. Bilden byggs upp med bland annat 2 st knappar, "Button"-objekt (se t ex Ericsson sid 367. Om lyssnare för knappar se sid 364). Räknaren skall "fungera", dvs när man trycker på knapparna skall minnet och textfönstret reagera. b) Skriv en klass UseCounters med ett huvudprogram som instansierar två Counter-objekt som kan användas för att räkna antalet bilar som svänger in på Osquars backe respektive Lindstedtsvägen. Förslag till utformning: Lindstedsvägen Osquars backe 6 16 Reset OneMore Reset OneMore c) Komplettera din counters-klass så att när man klickar på någon av stängningsrutorna hela programmet avslutas. 4. a) Skriv en enkel applet-java fil som gör att att vi med hjälp av appletviewer (eller en "bläddrare") får en tom applet som dock "rår om" de två räknarna i uppgift 3b). Dessa visas som två "Framar" som förut. b) Elegantare är att de två räknarna " flyttas" in i appleten. Hur gör man det? Svara med en nya varianter av Counters och applet-java-filen eller beskriv tydligt vilka ändringar som skall göras i de gamla filerna. Tips: Det går inte att stoppa "Framar" i applet-ytan. Namnet på räknarna, som i bilden ovan finns i "Frame"-titeln, skrev jag istället under knapparna.
Förslag till svar tentamen 2D4134 2000 juni 17. public class Stad { int inv; String name; public Stad(int iinv, String iname) { inv = iinv; name = iname; public String vilketnamn() { return name; public int antalinnevånare() { return inv; public String info() { return (name + " " + inv); ipublic class Stiftsstad extends Stad { String biskop; //1a //Tillägg 1e public Stiftsstad(int iinv, String iname, String ibiskop) { super(iinv, iname); biskop = ibiskop; public String vemärbiskop() { return biskop; public String info() { //Tillägg 1e return super.info() + " biskop : " + biskop; public class Residensstad extends Stad { String landsh; public Residensstad(int iinv, String iname, String ilandshövding){ super(iinv, iname); landsh = ilandshövding; public String vemärlandshövding() { return landsh; public String info() { //Tillägg 1e return super.info() + " landshövding : " + landsh;
//1b Det finns städer som "bara" är städer och måste kunna instansieras. Abstrakta klasser kan inte instansieras. public void skriv() { // 1c for (int i = 0; i < stad.length; i = i+1) { System.out.print(stad[i].vilketNamn() + " " + stad[i].antalinnevånare() + " "); if (stad[i] instanceof Residensstad) { System.out.println("lh : " + ((Residensstad) stad[i]).vemärlandshövding()); else if (stad[i] instanceof Stiftsstad) { System.out.println("biskp: "+ ((Stiftsstad) stad[i]).vemärbiskop()); else { System.out.println(); // 1d Vi tvingas ofta att skriva tillägg i användande klasser när ny subklasser av t ex stad införes, t ex i skriv()-metoden i 1 b)ovan. Svårt komplettera program. public void skrivoo() { // 1e for (int i = 0; i < stad.length; i = i+1) { System.out.println(stad[i].info()); //Även tillägg i de tre stadsklaserrna, se under 1 a. Stad [] stad = // 1f { new Stad(56658, "Örnsköldsvik"), new Residensstad(103517, "Umeå", "Georg Andersson"), new Stiftsstad(97975, "Lund", "Cristina Odelberg"); //1g Man får nöja sig med att ärva enkelt och ersätta det andra arvet med att implementera ett gränssnitt. Även klassen Stiftsstad låter man implementera gränssnittet. (Bättre språkligt låta SitftsstadIF heta Stiftsstad och döpa om Stiftsstad till RenStiftstad eller dylikt, men orkar inte göra detta.) public interface StiftsstadIF { public String vemärbiskop() ; public class StiftsOchResidensstad extends Residensstad implements StiftsstadIF{ String biskop;
public StiftsOchResidensstad(int iinv, String iname, String ibiskop, String ilandshövding) { super(iinv, iname, ilandshövding); biskop = ibiskop; public String vemärbiskop() { /implemntering av gränssitt return biskop; public String info() { return super.info() + " biskop : " + biskop; i = 10 j = 11 //2 i = 10 j = 100 i = 10 j = 11 i = 10 j = 11 a ={11,12 b ={15,9 a ={11,12 b ={121,144 a ={11,12 b ={15,9 a ={121,144 b ={15,9 Se import java.awt.*; import java.awt.event.*;; public class Counter extends Frame { private int n = 0; Button onemorebutton = new Button("OneMore"); Button resetbutton = new Button("Reset"); TextField window = new TextField(" "+n); // 3 a public Counter(String itext,int iwidth, int iheight) { setlayout(new BorderLayout(20,20)); add(resetbutton, BorderLayout.WEST); add(onemorebutton, BorderLayout.EAST); add(window, BorderLayout.NORTH); resetbutton.addactionlistener(new ResetListener(this)); onemorebutton.addactionlistener(new OneMoreListener(this)); setsize(iwidth, iheight); settitle(itext); setvisible(true); public void onemore() { n = n +1; shownumber(); public void reset() { n = 0; shownumber();
private void shownumber() { window.settext(" "+n); class OneMoreListener implements ActionListener{ Counter myc; public OneMoreListener(Counter ic) { myc = ic; public void actionperformed(actionevent e) { myc.onemore(); class ResetListener implements ActionListener{ Counter myc; public ResetListener(Counter ic) { myc = ic; public void actionperformed(actionevent e) { myc.reset(); public class UseCounters { //3b public static void main (String [] argv) { Counter c1 = new Counter("Lindstedtsvägen", 400,300); Counter c2 = new Counter("Osquars backe", 400,300); class WListener extends WindowAdapter { public void windowclosing(windowevent e) { System.exit(0); addwindowlistener(new WListener()); //Tillägg till konstrueraren i uppgift 5a import java.applet.* public class UseCountersApp extends Applet { //3c // 4a public void init() { Counter c1 = new Counter("Lindstedtsvägen", 400,300); Counter c2 = new Counter("Osquars backe", 400,300);
import java.awt.*; import java.applet.*; public class UseCountersApp extends Applet { // 4b // tillägg fet stil public void init() { setlayout(new FlowLayout()); Counter c1 = new Counter("Lindstedtsvägen", 400,300); Counter c2 = new Counter("Osquars backe", 400,300); add(c1); add(c2); setvisible(true); import java.awt.*; import java.awt.event.*;; public class Counter extends Panel { private int n = 0; Button onemorebutton = new Button("OneMore"); Button resetbutton = new Button("Reset"); TextField window = new TextField(" "+n); public Counter(String itext,int iwidth, int iheight) { setlayout(new BorderLayout(20,20)); setbackground(color.green); add(resetbutton, BorderLayout.WEST); add(onemorebutton, BorderLayout.EAST); add(window, BorderLayout.NORTH); add(new TextField(itext), BorderLayout.SOUTH); resetbutton.addactionlistener(new ResetListener(this)); onemorebutton.addactionlistener(new OneMoreListener(this)); setsize(iwidth, i height); // ignoreras i vissa fall setvisible(true);