Lunds universitet FYTA11 Institutionen för Teoretisk Fysik HT 08 Tentamen FYTA11 Javaprogrammering Fredag 9:e januari 2009, 09:00 13:00 Instruktioner Inga hjälpmedel är tillåtna. Behandla högst en uppgift per papper, skriv bara på ena sidan och sätt ditt namn och personnummer på varje sida. Skriv läsligt och kommentera utförligt vad du gör det kan ge dig poäng även om resultatet blir fel. Tentamen omfattar fyra uppgifter på fem sidor som alla kan ge upp till tio poäng. Uppgift 1: Leta buggar Titta på klasserna A, B, C samt D nedan. På nästa sida finns klassen ABCD. Om man kommentera bort de satser i main metoden i ABCD som ger kompileringsfel eller exekveringsfel, vad kommer då att skrivas ut om metoden exekveras? Förklara varför de bortkommenterade satser var felaktiga. Nedan visas också relevant information om standardklasen Vector. public abstract class A { public abstract String tostring(); return 0; public abstract class B extends A { return 1; public class C extends B { public String tostring() { return "C"; public class D extends C { return 3; package java.util; public class Vector<E> implements Collection<E> { /** Constructs an empty vector. */ public Vector(); /** Constructs a vector containing the elements * of the specified collection. */ public Vector(Collection<? extends E> c); /** Appends the specified element to the end of * this Vector. */ public boolean add(e e); //... 1
import java.util.*; public class ABCD { public static void main(string [] arg) { long l1 = 1; // 01 double x1 = 10.0; // 02 A a1 = new A(); // 03 B b1 = new B(); // 04 C c1 = new C(); // 05 D d1 = new D(); // 06 Object o1 = new C(); // 07 A a2 = new B(); // 09 B b2 = new C(); // 10 C c2 = new D(); // 11 D d2 = new C(); // 12 A a3 = (A) c1; // 14 B b3 = (B) d1; // 15 C c3 = (C) b2; // 16 D d3 = (D) b2; // 17 A a4 = o1; // 19 D d4 = (D) c2; // 20 long l2 = x1; // 22 double x2 = c1.tolong(); // 23 double x3 = (double) l1; // 24 long l3 = (long) x1; // 25 System.out.println(b1); // 27 System.out.println(c1); // 28 System.out.println(d1); // 29 System.out.println(b2 + " " + l1 + x1); // 30 System.out.println(b2 + l1 + " " + x1); // 31 System.out.println(c2 + " " + x1 + l1); // 32 System.out.println(d1 + " " + x1); // 33 System.out.println(a2.toLong()); // 34 System.out.println(b2.toLong()); // 35 System.out.println(c2.toLong()); // 36 Vector<D> vd = new Vector<D>(); // 38 vd.add(d1); // 39 vd.add(c2); // 40 vd.add(d4); // 41 Vector<A> va = vd; // 42 Vector<B> vb = new Vector<B>(vd); // 43 Vector<C> vc = vb; // 44 2
Uppgift 2: Personnummer Ett svenskt personnummer består av tio siffror (numera egentligen tolv efter som hela årtalet ska skrivas ut, men det bryr vi oss inte om här), där de sex första är födelsedatum på formen yymmdd och de fyra sista består av ett tre-siffrigt löpnummer (där den tredje siffran är udda för män och jämn för kvinnor) samt en kontrollsiffra. Kontroll siffran kan räknas ut på följande sätt. Multiplicera de enskilda siffrorna omväxlande med två eller ett enl. y y m m d d - n n n 2 1 2 1 2 1-2 1 2 Om en multiplikation blir större än eller lika med tio, lägg ihop siffrorna (t.ex. 8 2 = 16 1+6 = 7). Summera alla de resulterande siffrorna och ta 10 minus det resulterande entalet. Detta ger kontrollsiffran. Om entalet är noll blir även kontrollsiffran noll. Här är ett helt exempel: 8 1 2 2 2 8-9 8 7 x 2 1 2 1 2 1-2 1 2 16 1 4 2 4 8 18 8 14 7 1 4 2 4 8 9 8 5 : 48 10 8 x = 2 Skriv en klass med en metod som tar ett argument av typen int[]. Metoden ska kontrollera att heltalsfältet innehåller precis nio siffror mellan noll och nio. Under antagandet att dessa siffror är de första nio siffrorna i ett personnummer ska sedan kontroll siffran returneras som ett heltal. Om det upptäcks något fel med argumenten (fel antal, större än nio,...) ska ett exception av typen PNrException (se nedan) genereras. Notera att modulusoperatorn (%) som ger heltalsresten vid heltalsdivision, är mycket användbar här. public class PNrException extends Throwable { public PNrException() { super("the given numbers do not correspond to a personnummer."); Uppgift 3: Personnummer igen Lägg till en main metod i klassen från den förgående uppgiften som, för varje argument, skriver ut huruvida det är ett giltigt personnummer eller inte. Endast argument på formen yymmddnnnn, yymmdd-nnnn eller yymmdd nnnn accepteras och det ska kollas att sista siffran är korrekt. Notera att metoden public char charat(int i) ger tecknet med ett givet tecken, och att det som returneras är ett heltal motsvarande tecknets UTF8 kod. Notera också att koderna för tecknen 0,..., 9 är i nummerordning. 3
Uppgift 4: Personnummer igen igen Antag att klassen PNr nedan är den i vilken du har implementerat metoderna i de förgående två uppgifterna. Ett objekt av klassen skapar ett fönster med ett textfält (TextField), en etikett (Label) och en liten checkbox (Checkbox). Om man trycker på retur knappen i textfältet genereras en händelse av klassen ActionEvent för TextField objektet. När man klickar i checkboxen ändras den från markerad till omarkerad eller tvärt om, och en händelse av klassen ItemEvent genereras för Checkbox objektet. När objektet och fönstret skapas visar textfältet och etiketten de strängar som angetts i konstruktorerna. På samma sätt får checkboxen en text och visas omarkerad. Skriv de ändringar som krävs för att programmet ska fungera så att om man skriver in ett födelsedatum i textfältet och trycker på returtangenten, så ändras texten på etiketten och föreslår fyra sista siffror som ger ett korrekt personnummer. Om checkboxen är markerad ska de fyra siffrorna motsvara en kvinna, annars ska de motsvara en man. På nästa sida finns en del metoder i relevanta klasser och gränssnitt beskrivna. 4
import java.awt.*; public class PNr extends Frame { TextField textfield = new TextField("yymmdd"); Label label = new Label("nnnn"); Checkbox checkbox = new Checkbox("Female", false); public PNr() throws ArithmeticException { super("personnummer generator"); setlayout(new FlowLayout()); add(textfield); add(label); add(checkbox); pack(); setvisible(true); // metoderna som implementerats i uppgift 2 och 3. public class Label extends Component { /** Initializes a new instance of Label * with no text. */ public Label(); /** Initializes a new instance of Label * with the given text. * @param text The text for this label. */ public Label(String text); /** Sets the text in this label to the specified * value. * @param text The new text for this label. */ public synchronized void settext(string text); public class TextField extends TextComponent { /** get the text from the field */ public String gettext(); /** Assign an ActionListener to the field */ public void addactionlistener(actionlistener l); package java.awt.event; public interface ActionListener extends EventListener { /** Invoked when an action occurs. */ public void actionperformed(actionevent e); // Lots of other stuff... package java.awt.event; public class Checkbox extends Component { /** Create a checkbox with a given label * and a given state. */ public Checkbox(String label, boolean state); /** Get the current state of the checkbox. */ public boolean getstate(); /** Add an ItemListener which gets notified if * the state changes. */ public void additemlistener(itemlistener l); // Lots of other stuff... public interface ItemListener extends EventListener { /** Invoked when an item state is changed. */ public void itemstatechanged(itemevent e); public final class Math { /** Returns a double value with a positive sign, * greater than or equal to 0.0 and less than * 1.0. Returned values are chosen * pseudorandomly with (approximately) uniform * distribution from that range. */ public static double random(); 5