Kommentar: Metoderna getNummer i klasserna Lok och Tåg behövs egentligen inte i den här uppgiften, utan är till för att underlätta i uppgift 4.import java.util.List; import java.util.ArrayList; class Lok { private int nummer; private int vikt; public Lok(int nummer, int vikt) { this.nummer = nummer; this.vikt = vikt; } public int getNummer() { return nummer; } } class Vagn { private int tomvikt; private int lastvikt; public Vagn(int tomvikt, int lastvikt) { this.tomvikt = tomvikt; this.lastvikt = lastvikt; } } class Tåg { private Lok lok; private List<Vagn> vagnar = new ArrayList<Vagn>(); private Plats plats; public Tåg(Lok lok, Plats plats) { this.lok = lok; this.plats = plats; } public void åkTill(Plats destination) { plats = destination; } public void kopplaPåEnVagn(Vagn vagnen) { vagnar.add(vagnen); } public int getNummer() { return lok.getNummer(); } } abstract class Plats { } class Station extends Plats { private String namn; public Station(String namn) { this.namn = namn; } } class Sträcka extends Plats { private Station från; private Station till; public Sträcka(Station från, Station till) { this.från = från; this.till = till; } }
public static void main(String[] args) { Station örebro_central = new Station("Örebro Central"); Station örebro_södra = new Station("Örebro Södra"); Sträcka järnvägen = new Sträcka(örebro_central, örebro_södra); Lok lok1 = new Lok(1, 100); Lok lok2 = new Lok(2, 200); List<Vagn> alla_vagnar = new ArrayList<Vagn>(); for (int i = 0; i < 1000; ++i) alla_vagnar.add(new Vagn(10, 0)); Tåg tåg1 = new Tåg(lok1, örebro_central); tåg1.kopplaPåEnVagn(alla_vagnar.get(0)); tåg1.kopplaPåEnVagn(alla_vagnar.get(1)); tåg1.kopplaPåEnVagn(alla_vagnar.get(2)); Tåg tåg2 = new Tåg(lok2, örebro_södra); tåg2.kopplaPåEnVagn(alla_vagnar.get(3)); tåg1.åkTill(järnvägen); tåg2.åkTill(järnvägen); tåg1.åkTill(örebro_södra); }
class Tankvagn extends Vagn { private double volym; public Tankvagn(int tomvikt, int lastvikt, double volym) { super(tomvikt, lastvikt); this.volym = volym; } }
b) (1p)
.java-filen innehåller källkoden, dvs den Java-kod som programmeraren skrivit in (eller som, i vissa fall, genererats av något verktyg). .class-filen innehåller den kompilerad koden, som kompilerats av Java-kompilatorn och som kan köras av den virtuella Java-maskinen.
c) (2p)
Ja. Vi skriver en ny .java-fil, som i deluppgift a, och den kan sen kompileras av Java-kompilatorn. Den information om basklassen (Vagn) som den Java-kompilatorn behöver, kan den hämta från .class-filen Vagn.class.
I enlighet med hur polymorfism fungerar i objektorientering, kan sen variabler och metodparametrar av typen Vagn utan problem innehålla en Tankvagn, eftersom en Tankvagn ju är en sorts Vagn:
tåg2.kopplaPåEnVagn(new Tankvagn(10, 0, 17.2));
import java.net.ServerSocket; import java.net.Socket; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.PrintWriter; import java.io.IOException; import java.util.Map; import java.util.HashMap; class Klienttråd extends Thread { private final Socket socket; private final BufferedReader in; private final PrintWriter out; private final Spelet spelet; private Tåg tåget; public Klienttråd(Socket s, Spelet spelet) throws IOException { socket = s; this.spelet = spelet; in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); // true: PrintWriter is line buffered System.out.println("Klienttråd skapad."); // If any of the above calls throw an // exception, the caller is responsible for // closing the socket. Otherwise the thread // will close it. start(); // Starts the thread, and calls run() } public void run() { try { tåget = spelet.skapaNyttTåg(); out.println("TÅG " + tåget.getNummer()); out.println("Örebro Central"); while (true) { String kommando = in.readLine(); System.out.println("Klienttråd tog emot: " + kommando); if (kommando == null) { break; } try { if (kommando.equals("FLYTTA")) { String destinationsnamn = in.readLine(); Station destination = spelet.slåUppStation(destinationsnamn); if (destination == null) { out.println("NOK"); } else { tåget.åkTill(destination); out.println("OK"); } } else { out.println("NOK"); } } catch (NumberFormatException e) { out.println("Error!"); } } System.out.println("Klienttråd: Avslutar..."); } catch(IOException e) { System.out.println("Klienttråd: I/O-fel"); } finally { try { socket.close(); } catch(IOException e) { System.out.println("Klienttråd: Socketen ej stängd"); } } } // run } // class Klienttråd class Spelet { int antalLok = 0; private Map<String, Station> stationer = new HashMap<String, Station>(); public Spelet() { Station örebro_central = new Station("Örebro Central"); stationer.put("Örebro Central", örebro_central); Station örebro_södra = new Station("Örebro Södra"); stationer.put("Örebro Södra", örebro_södra); Station kumla = new Station("Kumla"); stationer.put("Kumla", kumla); } public synchronized Tåg skapaNyttTåg() { Lok loket = new Lok(++antalLok, 100); Tåg tåget = new Tåg(loket, stationer.get("Örebro Central")); Vagn vagnen = new Vagn(10, 20); tåget.kopplaPåEnVagn(vagnen); return tåget; } public Station slåUppStation(String namnet) { return stationer.get(namnet); } } // Spelet public class Tågserver { public static final int PORT = 2000; public static void main(String[] args) throws IOException { Spelet spelet = new Spelet(); ServerSocket ss = new ServerSocket(PORT); System.out.println("Server-socketen: " + ss); System.out.println("Servern lyssnar..."); try { while(true) { // Blocks until a connection occurs: Socket socket = ss.accept(); System.out.println("Uppkoppling accepterad."); System.out.println("Den nya socketen: " + socket); try { Klienttråd t = new Klienttråd(socket, spelet); System.out.println("Ny tråd skapad."); System.out.println("Den nya tråden: " + t); } catch(IOException e) { // If the constructor fails, close the socket, // otherwise the thread will close it: socket.close(); } } } finally { ss.close(); } } // main } // Tågserver
Först en rent textbaserad klient:
import java.net.InetAddress; import java.net.Socket; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.PrintWriter; import java.io.IOException; public class Tågklient { public static final int PORT = 2000; public static void main(String[] args) throws IOException { InetAddress addr = InetAddress.getByName("localhost"); Socket socket = new Socket(addr, 2000); System.out.println("Uppkopplad..."); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream())), true); BufferedReader kbd_reader = new BufferedReader( new InputStreamReader(System.in)); in.readLine(); // Ska vara t. ex. "TÅG 17" String aktuellPosition = in.readLine(); // Ska vara t. ex. "Örebro Central" while (true) { System.out.println("Tåget befinner sig nu här: " + aktuellPosition); System.out.println("Ange vart du vill köra tåget (Q för att avsluta): "); String destination = kbd_reader.readLine(); if (destination.equals("Q")) break; else { out.println("FLYTTA"); out.println(destination); String status = in.readLine(); if (status == null) break; else if (status.equals("OK")) aktuellPosition = destination; else System.out.println("Det gick inte!"); } } } } // Tågklient
Därefter en grafisk klient:
import java.net.InetAddress; import java.net.Socket; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.PrintWriter; import java.io.IOException; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class GrafiskTågklient extends JFrame { public static final String SERVER = "localhost"; public static final int PORT = 2000; JLabel platsetiketten = new JLabel("Tågets plats:"); JTextField platsfältet = new JTextField(20); JLabel destinationsetiketten = new JLabel("Destination:"); JTextField destinationsfältet = new JTextField(20); JLabel resultatlabeln = new JLabel("Status:"); JTextField resultatfältet = new JTextField(20); JButton körknappen = new JButton("Kör dit"); JButton slutaknappen = new JButton("Sluta"); Socket socketen; BufferedReader frånServern; PrintWriter tillServern; String aktuellPosition; // Ska vara t. ex. "Örebro Central" public GrafiskTågklient() { super("Grafisk Tågklient"); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(platsetiketten); cp.add(platsfältet); cp.add(destinationsetiketten); cp.add(destinationsfältet); cp.add(resultatlabeln); cp.add(resultatfältet); cp.add(körknappen); cp.add(slutaknappen); setSize(350, 140); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void kopplaUpp() { try { InetAddress adressen = InetAddress.getByName("localhost"); socketen = new Socket(adressen, 2000); frånServern = new BufferedReader( new InputStreamReader( socketen.getInputStream())); tillServern = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socketen.getOutputStream())), true); String tågnummer = frånServern.readLine(); aktuellPosition = frånServern.readLine(); platsfältet.setText(aktuellPosition); resultatfältet.setText("Uppkopplad."); } catch (IOException e) { resultatfältet.setText("Fel!"); } körknappen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { try { String destination = destinationsfältet.getText(); tillServern.println("FLYTTA"); tillServern.println(destination); String status = frånServern.readLine(); if (status == null) resultatfältet.setText("Fel!"); else if (status.equals("OK")) { aktuellPosition = destination; platsfältet.setText(aktuellPosition); resultatfältet.setText("OK."); } else resultatfältet.setText("Gick inte."); } catch (IOException e) { resultatfältet.setText("Fel!"); } } }); slutaknappen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); } public static void main(String[] args) throws IOException { GrafiskTågklient klienten = new GrafiskTågklient(); klienten.kopplaUpp(); } } // GrafiskTågklient