You are on page 1of 8

Π Π

Τ Ε Τ Υ
Μαθημα: Αντικειμενοστρεφής Προγραμματισμός
Εξεταση: Επαναληπτική 2012–2013 Ημερομηνια: 5 / 9 / 2013

Ονοματεπωνυμο: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Α.Μ.: . . . . . . . . . . . . . . . . . . . . . . . . .

[54] Θέμα 1 — Λυση


Μια κλαση Pixel αναπαριστα τις συντεταγμενες ενος εικονοστοιχειου:

public class Pixel


{
public static int MAX_X = 1280;
public static int MAX_Y = 800;

public int x, y;
}

Υποθετουμε οτι το προγραμμα μας χειριζεται εικονες συγκεκριμενων διαστασεων MAX_X × MAX_Y
(π.χ. 1280 × 800), επομενως οι συντεταγμενες x και y καθε σημειου πρεπει να ειναι στα ορια 0 ≤
x < MAX_X και 0 ≤ y < MAX_Y.
[4] α) Τι σημαινει το προσδιοριστικο static στις παραπανω δηλωσεις;
Τι σημαινει η απουσια του προσδιοριστικου final στις παραπανω δηλωσεις;
Το προσδιοριστικο static σημαινει οτι τα πεδια MAX_X και MAX_Y ανηκουν στην κλαση, δηλαδη απο
κοινου σε ολα τα αντικειμενα της, και οχι σε καθε χωριστο αντικειμενο οπως τα υπολοιπα πεδια. Με
αλλα λογια, η τιμη των πεδιων αυτων ειναι κοινη για ολα τα αντικειμενα της κλασης.
Το προσδιοριστικο final χαρακτηριζει κατι ως σταθερα. Αφου εδω δεν υπαρχει, σημαινει οτι οι τιμες
αυτες μπορουν να αλλαξουν.

[5] β) Με βαση τον κωδικα που δινεται, γραψτε κωδικα που να δημιουργει ενα Pixel με ονομα p και
συντεταγμενες (300, 200).
Επισης γραψτε κωδικα που να αλλαζει το μεγιστο οριο της συντεταγμενης x σε 1024.

Pixel p = new Pixel();


p.x = 300;
p.y = 200;

Pixel.MAX_X = 1024; // ή και, λιγότερο καλά: p.ΜΑΧ_Χ = 1024

[4] γ) Δινεται η ακολουθη μεθοδος (που υπαρχει εκτος της κλασης Pixel):
public void setCoords(Pixel pix)
{
// Δημιουργία ενός νέου Pixel και απόδοση σε αυτό συντεταγμένων
// x=400, y=800
Pixel temp;
// ...

pix = temp;
}
και η κληση αυτης για το Pixel του προηγουμενου ερωτηματος

σελ. 1 / 8
setCoords(p);
Ποιες οι τιμες των συντεταγμενων του p μετα απο αυτη την κληση, και γιατι;
Οι τιμες των συντεταγμενων του p παραμενουν (300, 200) καθως μεσα στη μεθοδο αντιστοιχιζεται
στην παραμετρο pix μια νεα αναφορα, ομως η αντιστοιχιση αυτη παυει να υφισταται μετα το τελος της
κλησης της μεθοδου. Αυτο συμβαινει γιατι η μεταβλητη pix ειναι μια νεα αναφορα προς το αντικειμενο
που δειχνει και η μεταβλητη p· μεσα στη μεθοδο η pix δειχνει στο αντικειμενο temp, ομως στο τελος η
pix καταστρεφεται και ετσι η p δειχνει στο αρχικο αντικειμενο και εχει τις ιδιες τιμες συντεταγμενων.

[5] δ) Υλοποιηστε μεθοδο toString() και χρησιμοποιηστε την για να εμφανισετε στην οθονη το
παραπανω εικονοστοιχειο στη μορφη «(300, 200)».

public String toString()


{
return ("(" + x + ", " + y + ")");
}

και

System.out.println(p);

[5] ε) Προσθεστε στην κλαση Pixel μια μεθοδο


void setX(int x)
η οποια να αναθετει την τιμη που δινεται ως παραμετρος στη συντεταγμενη x του εικονοστοι-
χειου, μονο εφοσον η τιμη αυτη ειναι εντος οριων, διαφορετικα να προκαλει μια ελεγχομενη
εξαιρεση του τυπου CoordinateOutOfBoundsException.

public void setX(int x) throws CoordinateOutOfBoundsException


{
if (x >= 0 && x < MAX_X) {
this.x = x;
}
else {
throw new CoordinateOutOfBoundsException();
}
}

[13] στ) Υποθετοντας οτι στην κλαση Pixel υπαρχει και μια αντιστοιχη μεθοδος setY(), γραψτε πληρη
μεθοδο main() (εκτος της κλασης Pixel) που να διαβαζει απο το πληκτρολογιο τις συντεταγ-
μενες 10 (εγκυρων) εικονοστοιχειων και τα καταχωριζει σε (απλο) πινακα. Η εγκυροτητα των
συντεταγμενων θα πρεπει να ελεγχεται μεσω των μεθοδων setX() και setY().

public static void main(String[] args)


{
Pixel[] pixels = new Pixel[10];

Scanner input = new Scanner(System.in);

int i = 0;
while (i < 10) {
boolean ok = true;

try {
Pixel p = new Pixel();

p.setX(input.nextInt());

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 2 / 8


p.setY(input.nextInt());

pixels[i] = p;
}
catch (CoordinateOutOfBoundsException e) {
ok = false;
}

if (ok) {
i++;
}
}
}

[4] ζ) Αν εκτελεστει ο κωδικας που γραψατε για το προηγουμενο ερωτημα και ο χρηστης δωσει ως
εισοδο μια συμβολοσειρα αντι για καποιον απο τους ακεραιους που διαβαζονται, τι θα συμβει,
και γιατι; Αν υπαρξει προβλημα, περιγραψτε πως θα μπορουσατε να το αποφυγετε.
Η μεθοδος nextInt() του Scanner θα προκαλεσει εξαιρεση (InputMismatchException) και θα τερμα-
τιστει η λειτουργια του προγραμματος. Για να αποφυγουμε το προβλημα θα επρεπε να προσθεσουμε
ακομα ενα catch για αυτο τον τυπο εξαιρεσης πριν η μετα το υπαρχον. Εναλλακτικα θα μπορουσε να
χρησιμοποιηθει η μεθοδος hasNextInt() του Scanner ωστε να ελεγχθει αν υπαρχει ακεραιος και να
γινει καταλληλος χειρισμος στην περιπτωση που δεν υπαρχει.

[6] η) Υλοποιηστε την κλαση ελεγχόμενης εξαιρεσης CoordinateOutOfBoundsException.


Τι θα επρεπε να αλλαξετε για να γινει μη ελεγχόμενη εξαιρεση;
Ποια επιπτωση θα ειχε αυτη η αλλαγη σε κωδικα που χρησιμοποιει τη μεθοδο setX() και στην
εκτελεση του προγραμματος;

public class CoordinateOutOfBoundsException extends Exception


{
public CoordinateOutOfBoundsException()
{
super();
}

public CoordinateOutOfBoundsException(String message)


{
super(message);
}
}

Για να ειναι μη ελεγχομενη η εξαιρεση, θα επρεπε απλως να αλλαξει η κλαση που κληρονομει:

extends RuntimeException

Αν η εξαιρεση ηταν μη ελεγχομενη, θα μπορουσε η μεθοδος setX() να χρησιμοποιειται (καλειται) χωρις


να πρεπει να μπει μεσα σε try ... catch. Αν συνεβαινε εξαιρεση, απλως θα σταματουσε η εκτελεση
του προγραμματος.

[8] θ) Γραψτε κωδικα με τον οποιο τα αντικειμενα του πινακα του παραπανω ερωτηματος εγγραφο-
νται σε δυαδικό σειριακό αρχειο. Υπενθυμιζονται οι διαφορες κλασεις εγγραφης σε αρχεια:
FileOutputStream, PrintWriter, ObjectOutputStream, RandomAccessFile.
Επισημανετε αν χρειαζονται αλλαγες στην κλαση Pixel.

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 3 / 8


try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.obj"));

for (int j = 0; j < 10; j++) {


oos.writeObject(pixels[j]);
}

oos.close();
}
catch (FileNotFoundException e) { // Μπορεί και να μην υπάρχει, καθώς είναι
System.err.println(e); // υποκλάση της IOException
}
catch (IOException e) {
System.err.println(e);
}

Επισης η κλαση Pixel πρεπει να υλοποιει το interface Serializable:

public class Pixel implements Serializable

[46] Θέμα 2 — Λυση


Δινονται οι ακολουθες δυο κλασεις: η Item αντιπροσωπευει ενα προϊον που αγοραζει ο πελατης
ενος καταστηματος, ενω η Basket αντιπροσωπευει ολα τα προϊοντα που εχει αγορασει.
[8] α) Καποια στοιχεια της κλασης Basket δεν εχουν χαρακτηρισμο public (γραμμες 25 και 39). Τι
τυπου προσβαση υπαρχει σε αυτα; Συγκρινετε αυτου του τυπου την προσβαση με αυτη που
προσδιδουν τα χαρακτηριστικα public, private και protected και καταταξτε τα τεσσερα
ειδη προσβασης ως προς το ποσο περιοριστικα ειναι.
Η προσβαση ειναι τυπου πακετου. Κατα αυξουσα σειρα περιοριστικοτητας, οι τυποι προσβασης ειναι:
1. public: Προσβαση απο ολους.
2. protected: Προσβαση απο τις υποκλασεις.
3. Πακετου: Προσβαση απο τις κλασεις που βρισκονται στο ιδιο πακετο. Ειναι πιο περιοριστικη απο
την προσβαση protected καθως αν ο φακελος που αντιστοιχει στο πακετο της κλασης εχει πε-
ριορισμενη προσβαση μεσω του λειτουργικου, τοτε περιοριζεται αμεσως και η προσβαση μεσω
της Java. Αντιθετα, μια υποκλαση μπορει να ανηκει σε διαφορετικο πακετο απο την υπερκλαση
της, επομενως μπορει να εχει προσβαση σε protected στοιχεια της ακομα και αν το πακετο της
υπερκλασης ειναι «κλειδωμενο»
4. private: Προσβαση μονο απο την ιδια την κλαση.

[8] β) Οι δυο σταθερες στην αρχη της κλασης Item χρησιμοποιουνται για να διακριθει το ειδος του
προϊοντος. Αντικαταστηστε τις σταθερες αυτες με μια απαριθμηση (enum) και αναφερετε ανα-
λυτικα τις αλλαγες που πρεπει να γινουν σε ολο τον κωδικα εξαιτιας αυτης της αντικαταστα-
σης (δωστε αριθμους γραμμων του κωδικα και τον νεο κωδικα η επαρκη περιγραφη του).
Η ζητουμενη απαριθμηση ειναι η ακολουθη:

public enum ItemType


{
UNIT_ITEM, WEIGHT_ITEM
}

Οι απαιτουμενες αλλαγες ειναι:


• Προφανως αφαιρουνται οι γραμμες 3–4.

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 4 / 8


• Στη γραμμη 6 αντι για int μπαινει ItemType.
• Στη γραμμη 11 επισης η παραμετρος int type γινεται ItemType type.
• Στη γραμμη 41 αντι για item.UNIT_ITEM μπαινει ItemType.UNIT_ITEM και αντιστοιχα στη γραμμη
44.

[30] γ) Ο αρχικος κωδικας δεν ακολουθει τις αρχες του αντικειμενοστρεφους προγραμματισμου και
μπορει να βελτιωθει χρησιμοποιωντας κληρονομικοτητα. Ξαναγραψτε τον κωδικα
• αποκρυπτοντας τα πεδια των κλασεων,
• προσθετοντας στην κλαση Item μια μεθοδο value() που να κανει, για καθε υποκλάση
της που θα δημιουργησετε, τους υπολογισμους που τωρα γινονται στη μεθοδο itemValue()
της κλασης Basket επιστρεφοντας την αξια του αντιστοιχου προϊοντος,
• αντικαθιστωντας τον απλο πινακα items της κλασης Basket απο καταλληλο ArrayList<>
και εκμεταλλευομενοι τις δυνατότητές του.
1 public class Item
2 {
3 public static final int UNIT_ITEM = 0;
4 public static final int WEIGHT_ITEM = 1;
5

6 public int type;


7 public String description;
8 public double quantity;
9 public double price;
10

11 public Item(int type, String description, double quantity, double price)


12 {
13 this.type = type;
14 this.description = description;
15 this.quantity = quantity; // Only for WEIGHT_ITEMs, see Basket.itemValue()
16 this.price = price;
17 }
18 }
19

20 ////////////////////////////////////////////////////////////////////////////////
21

22 public class Basket


23 {
24 Item[] items;
25 int itemCount;
26

27 public Basket()
28 {
29 items = new Item[100]; // Big enough to hold everything, hopefully!
30 itemCount = 0;
31 }
32

33 public void addItem(Item item)


34 {
35 items[itemCount] = item;
36 itemCount++;

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 5 / 8


37 }
38

39 double itemValue(Item item)


40 {
41 if (item.type == item.UNIT_ITEM) {
42 return item.price;
43 }
44 else { // in this case, item.type == item.WEIGHT_ITEM
45 return item.price * item.quantity;
46 }
47 }
48

49 public double totalValue()


50 {
51 double sum = 0.0;
52 for (int i = 0; i < itemCount; i++) {
53 sum += itemValue(items[i]);
54 }
55

56 return sum;
57 }
58 }
Οι αλλαγες συνοψιζονται στα εξης:
• Όλα τα πεδια εγιναν private και προστεθηκαν μεθοδοι προσβασης οπου χρειαζοταν (εδω οι
μεθοδοι get στην υπερκλαση ειναι απαραιτητες για προσβαση των πεδιων απο τις υποκλασεις.
• Το πεδιο type δεν χρειαζεται πλεον, οι δυο τυποι προϊοντων αντιπροσωπευονται απο διαφορε-
τικες κλασεις.
• Η Item εγινε αφηρημενη υπερκλαση κρατωντας μονο τα κοινα στοιχεια των δυο υποκλασεων
(το πεδιο quantity πηγε μονο στην κλαση WeightItem καθως δεν χρησιμοποιειται στην UnitItem).
Αφηρημενη ειναι η μεθοδος value() καθως δεν εχει νοημα να επιστρεψει κατι για την κλαση
Item.
• Χρησιμοποιωντας το ArrayList<> δεν χρειαζεται πλεον να μετραμε ποσα στοιχεια εχουν μπει
στον πινακα, ουτε ασφαλως να προκαθοριζουμε το μεγιστο μεγεθος του.
• Η τελικη αξια υπολογιζεται καλωντας πολυμορφικα τις μεθοδους value() των υποκλασεων.
public abstract class Item
{
private String description;
private double price;

public Item(String description, double price)


{
this.description = description;
this.price = price;
}

public String getDescription()


{
return description;
}

public double getPrice()

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 6 / 8


{
return price;
}

public abstract double value();


}

////////////////////////////////////////////////////////////////////////////////

public class UnitItem extends Item


{
public UnitItem(String d, double p)
{
super(d, p);
}

public double value()


{
return getPrice();
}
}

////////////////////////////////////////////////////////////////////////////////

public class WeightItem extends Item


{
private double quantity;

public WeightItem(String d, double p, double q)


{
super(d, p);
quantity = q;
}

public double value()


{
return getPrice() * quantity;
}
}

////////////////////////////////////////////////////////////////////////////////

public class Basket


{
private ArrayList<Item> items;

public Basket()
{
items = new ArrayList<>();
}

public void addItem(Item item)


{
items.add(item);
}

public double totalValue()

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 7 / 8


{
double sum = 0.0;
for (int i = 0; i < items.size(); i++) {
sum += items.get(i).value();
}

return sum;
}
}

Αντικειμενοστρεφης Προγραμματισμος 5 / 9 / 2013 σελ. 8 / 8

You might also like