Örebro universitet
Institutionen för teknik
Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se)







Ordinarie tentamen i

Programmering i Java

för Dataingenjörsprogrammet m fl

torsdag 16 december 2004 kl 14:00 - 19:00







Hjälpmedel: Inga hjälpmedel.
Poängkrav: Maximal poäng är 42.
För betyget 3 krävs 21 poäng.
För betyget 4 krävs 28 poäng.
För betyget 5 krävs 35 poäng.
Resultat och lösningar: Meddelas på kursens hemsida senast torsdag 6 januari 2005.
Visning: Måndag 10 januari 2004 kl 13:00-13:30 i mitt rum (T2220).
Efter visningen kan tentor hämtas på expeditionen.
Examinator och jourhavande: Thomas Padron-McCarthy, telefon 070-7347013.



LYCKA TILL!

Skriv inte svaren till uppgifterna direkt här, utan skriv på lösa blad och lämna in.

Uppgift 1 (3p)

Äldre programmeringsspråk, som C, C++ och Ada, brukar kompileras till maskinkod som kan köras av en viss processor. Java kompileras i stället till kod som kan köras av en virtuell maskin.

a) (1p) Hur skiljer sig denna virtuella maskin från en vanlig maskin, till exempel den här datorn med en Pentium-processor som står här på mitt skrivbord?

b) (2p) Vilka fördelar och nackdelar finns med att kompilera till en virtuell maskin?

Uppgift 2 (5p)

a) (2p)

Skapa en klass som heter Mask. Varje mask har en längd, som anges av ett heltal. Det ska också finnas en klassvariabel som är av typen Mask och som anger vilken som är den längsta masken. Klassen ska ha en konstruktor som tar längden på den nya masken som argument, och som om det behövs uppdaterar klassvariabeln med den längsta masken.

b) (3p)

Skapa en annan klass, Äpple. Ett äpple kan innehålla en mask. Om man skickar ett argument i form av en mask till konstruktorn ska den masken stoppas in i äpplet, men annars ska äpplet vara maskfritt från början. Det ska finnas metoder som gör att man kan stoppa in en mask i äpplet, och plocka bort masken ur äpplet. Skapa också två undantagstyper, ÄppletRedanFulltException och ÄppletRedanTomtException, som kastas om man försöker stoppa in en mask i ett äpple som redan har en mask, respektive ta bort en mask ur ett äpple som inte har någon mask.

Exempel på kod som använder de två klasserna:

        Mask m1 = new Mask(14);
        Mask m2 = new Mask(17);
        Äpple ä1 = new Äpple();
        Äpple ä2 = new Äpple(m1);
        try {
            ä1.taBortMasken();
            ä2.stoppaInEnMask(m1);
            ä2.stoppaInEnMask(m2);
        }
        catch (ÄppletRedanTomtException e) {
            System.err.println("Äpplet var redan tomt.");
        }
        catch (ÄppletRedanFulltException e) {
            System.err.println("Äpplet var redan fullt.");
        }

Uppgift 3 (4p)

Vad skrivs ut när följande Java-program körs?
class X {
    private int x;
    public X(int x) {
        System.out.println("Skapar en X(" + x + ").");
        this.x = x;
    }
    public X() {
        this(0);
        System.out.println("Skapar en X().");
    }
    public void f() {
        System.out.println("X.f");
    }
} // X

class XYZ extends X {
    private int y;
    private int z;
    public XYZ(int x, int y, int z) {
        super(x);
        System.out.println("Skapar en XYZ(" + x + ", " + y + ", " + z + ").");
        this.y = y;
        this.z = z;
    }
    public XYZ(int y, int z) {
        super();
        System.out.println("Skapar en XYZ(" + y + ", " + z + ").");
        this.y = y;
        this.z = z;
    }
    public void f() {
        System.out.println("XYZ.f");
    }
} // X

public class Uppgift3 {
    X x;
    public Uppgift3() {
        x = new XYZ(1, 2, 3);
    }
    public static void main(String [] args) {
        Uppgift3 u = new Uppgift3();
        X x1 = new X();
        X x2 = new XYZ(4, 5, 6);
        XYZ xyz = new XYZ(17, 19);
        u.f(x1);
        g(x2);
    } // main
    public void f(X x) {
        System.out.println("Uppgift3.f");
        x.f();
        this.x.f();
    }
    static public void g(X x) {
        System.out.println("Uppgift3.g");       
        x.f();
    }
} // Uppgift3

Uppgift 4 (15p)

Skrive en applet som visar temperaturdata. Appleten ska koppla upp sig mot port 3003 på ett serverprogram, som vi kan anta kör på samma dator som vi använder för att titta på appleten. Servern skickar då och då temperaturdata till appleten, och då ska appleten visa dessa, gärna i ett textfönster. Det kan se ut till exempel så här:
Bild på appleten
De data som skickas från servern består av en rad med ett ortsnamn (till exempel Kiruna) och en temperatur (till exempel -16). Exempel:
Stockholm 9
Madrid 23
Kumla 7
Kiruna -16
Appleten ska inte skicka några förfrågningar till servern, utan servern skickar automatiskt ut nya temperaturdata så fort de blir tillgängliga.

När man startar appleten har den alltså inga temperaturdata att visa, och då är textfönstret tomt. Allteftersom nya data kommer, fylls dessa på i textfönstret.

Det ska finnas en knapp, till exempel märkt Rensa, som rensar bort alla temperaturer som kommit hittills.

Om det inte går att koppla upp mot servern, eller om servern kopplar ner förbindelsen, ska man få en felutskrift i fönstret:

Bild på appleten med en felutskrift
Det finns inga krav på att appleten ska se ut exakt som på bilderna. Den behöver inte vara vacker, bara temperaturerna och Rensa-knappen finns med.

Vi kan anta att alla utskrifter alltid får plats i fönstret, så det behövs inga rullningslister. Vi kan också anta servern aldrig skickar felaktiga rader, så man behöver ingen särskild hantering av protokollfel.

För full poäng på uppgiften krävs att appleten inte skriver ut dubletter av städer. Om servern skickar en ny temperatur för Kiruna, ska alltså den gamla temperaturen tas bort. (Om man tillåter dubletter blir appleten mycket enklare, eftersom man bara behöver ta raderna som kommer från servern och direkt skriva ut dem i fönstret.) En lösning som tillåter dubletter ger högst tio poäng.

Några tips:

Applet-klassen i Swing-paketet heter JApplet.

Knappklassen heter JButton, och den har en metod som heter addActionListener. Som argument tar den metoden ett objekt som uppfyller gränssnittet ActionListener. Gränssnittet ActionListener innehåller metoden actionPerformed, som tar ett argument av typen ActionEvent.

Klassen (JTextArea) kan användas för textfönstret. Klassen JTextArea har metoderna setText och append.

Uppgift 5 (5p)

a) (2p)

I uppgiften ovan skulle du skriva en Java-applet. En Java-applet är en speciell sorts Java-program. En annan sorts Java-program kallas Java-applikationer. Vad är skillnaderna mellan en applet och en applikation?

b) (2p)

Det är praktiskt att kunna köra en applet som en applikation. Förklara hur man gör för att skriva en applet som samtidigt kan köras som en applikation.

c) (1p)

Ovan skrev jag att det är praktiskt att kunna köra en applet som en applikation. Varför är det det?

Uppgift 6 (10p)

Skriv en serverapplikation som kan användas för att testköra appleten i uppgift 4. Välj själv hur serverapplikationen ska fungera för att på ett bra sätt kunna testa din applet.

Beskriv också hur man använder serverapplikationen för att testa appleten!

För full poäng på uppgiften krävs att serverapplikationen klarar att hantera flera olika appletar som samtidigt är uppkopplade. En lösning som bara klarar en enda applet ger högst fem poäng.

Bilaga: Utdrag ur API-specifikationen

java.net
Class ServerSocket

java.lang.Object
  extended byjava.net.ServerSocket

ServerSocket(int port)
          Creates a server socket, bound to the specified port.

Socket accept()
          Listens for a connection to be made to this socket and accepts it.

void close()
          Closes this socket.




java.net
Class Socket

java.lang.Object
  extended byjava.net.Socket

Socket()
          Creates an unconnected socket, with the system-default type of SocketImpl.

Socket(InetAddress address, int port)
          Creates a stream socket and connects it to the specified port number at the specified IP address.

void close()
          Closes this socket.

InputStream getInputStream()
          Returns an input stream for this socket.

OutputStream getOutputStream()
          Returns an output stream for this socket.

java.io
Class BufferedReader

java.lang.Object
  extended byjava.io.Reader
      extended byjava.io.BufferedReader

BufferedReader(Reader in)
          Create a buffering character-input stream that uses a default-sized input buffer.

void close()
          Close the stream.

int read()
          Read a single character.

String readLine()
          Read a line of text.




java.io
Class InputStreamReader

java.lang.Object
  extended byjava.io.Reader
      extended byjava.io.InputStreamReader

InputStreamReader(InputStream in)
          Create an InputStreamReader that uses the default charset.

void close()
          Close the stream.

int read()
          Read a single character.

java.io
Class PrintWriter

java.lang.Object
  extended byjava.io.Writer
      extended byjava.io.PrintWriter

PrintWriter(OutputStream out)
          Create a new PrintWriter, without automatic line flushing, from an existing OutputStream.

PrintWriter(OutputStream out, boolean autoFlush)
          Create a new PrintWriter from an existing OutputStream.

void close()
          Close the stream.

void println()
          Terminate the current line by writing the line separator string.

void println(String x)
          Print a String and then terminate the line.

java.net
Class InetAddress

java.lang.Object
  extended byjava.net.InetAddress

public static InetAddress getByName(String host)
                             throws UnknownHostException
          Determines the IP address of a host, given the host's name.