Αντικειμενοστρεφής Προγραμματισμός — Σεπτέμβριος 2025¶
Μεταγραφή από τις φωτογραφίες CamScanner_12-9-25 (σελίδες 1, 2 και 3 από 4).
CamScanner_12-9-25_05.33_1.jpg¶
Θέμα 1ο (2 μονάδες): Ποια είναι η έξοδος στις παρακάτω περιπτώσεις; Απαντήστε και δώστε σύντομη εξήγηση.
a.
LinkedList<String> queue = new LinkedList<>();
queue.add("C");
queue.add("B");
queue.add("A");
System.out.println(queue.remove());
System.out.println(queue.remove());
b.
HashSet<Integer> set = new HashSet<>();
set.add(5);
set.add(10);
set.add(5);
set.add(15);
System.out.println(set.size());
c.
String s1 = "Hello";
String s2 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
d.
int result = 0;
for (int i = 0; i < 5; i++) {
if (i == 2) continue;
if (i == 4) break;
result += i;
}
System.out.println(result);
Θέμα 2ο (2 μονάδες): Ποια είναι η έξοδος στις παρακάτω περιπτώσεις; Απαντήστε και δώστε σύντομη εξήγηση.
a.
Stack<Integer> stack = new Stack<>();
for (int i = 3; i > 0; i--) {
stack.push(i);
stack.push(i+1);
System.out.print(stack.pop() + " ");
}
b.
class Counter {
private int count;
public void increment() {
count++;
}
}
public class Main
{
public static void main(String[] args) {
Counter c = new Counter();
c.increment();
System.out.println(c.count);
}
}
1/4
CamScanner_12-9-25_05.34_1.jpg¶
c.
boolean[] arr = new boolean[5];
System.out.println(arr[4]);
d.
public class Example {
private int value;
public Example(int value) {
this.value = value;
}
public static void main(String[] args) {
Example e1 = new Example(10);
Example e2 = new Example(10);
System.out.println(e1 == e2);
}
}
Θέμα 3ο (2 μονάδες): Υλοποιήστε την κλάση Book ώστε να υποστηρίζεται ο παρακάτω κώδικας. Αποφύγετε επανάληψη κώδικα. Απαντήστε στο χώρο που δίνεται.
Student s1 = new Student("Alice");
Student s2 = new Student("Bob", 12345);
Student s3 = new Student("Charlie", 67890, 2023);
s1.display(); // Name: Alice, ID: Unknown, Year: -1
s2.display(); // Name: Bob, ID: 12345, Year: -1
s3.display(); // Name: Charlie, ID: 67890, Year: 2023
Θέμα 4ο (1,5 μονάδες): Συμπληρώστε τον κώδικα της συνάρτησης setValue, η οποία θέτει την τιμή value στην θέση index του πίνακα arr. Χειριστείτε την εξαίρεση ArrayIndexOutOfBoundsException που προκύπτει αν η τιμή του index είναι εκτός των ορίων του πίνακα. Συμπληρώστε στη main τη δημιουργία του πίνακα myArray .
public class ArrayExceptionHandling {
public static void setValue(int[] arr, int index, int value) {
// Α: συμπληρώστε αυτό το τμήμα
}
public static void main(String[] args) {
// Β: συμπληρώστε για δήλωση και δέσμευση πίνακα ακεραίων myArray 10 θέσεων
setValue(myArray, 1, 50);
setValue(myArray, 20, 100);
}
}
2/4
CamScanner_12-9-25_05.341_1.jpg¶
ΘΕΜΑ 5ο (1 μονάδα): Επιλέξτε τη σωστή απάντηση για κάθε ερώτηση παρακάτω.
i. ________ χρησιμοποιείται/ούνται για προγραμματισμό με γενικεύσεις (generics) - [ ] Α. Η κληρονομικότητα - [ ] Β. Οι εικονικές συναρτήσεις - [ ] Γ. Τα πρότυπα - [ ] Δ. Κανένα από τα παραπάνω
ii. Η σύνδεση του κώδικα με τυχόν βιβλιοθήκες που χρησιμοποιεί γίνεται στη C++ από: - [ ] Α. Τον compiler - [ ] Β. Τον preprocessor - [ ] Γ. Τον linker - [ ] Δ. Τη CPU
iii. Όταν υπερφορτώνουμε έναν δυαδικό τελεστή ως μέλος κλάσης: - [ ] Α. Το αριστερό μέλος του τελεστή είναι το αντικείμενο για το οποίο καλείται - [ ] Β. Το δεξιά μέλος του τελεστή είναι το αντικείμενο για το οποίο καλείται - [ ] Γ. Το αριστερό μέλος του τελεστή είναι το όρισμα της συνάρτησης - [ ] Δ. Θα πρέπει να δηλωθεί ως friend
iv. Τι από τα παρακάτω ισχύει για ένα αντικείμενο που δημιουργείται δυναμικά; - [ ] Α. Ο τελεστής delete καλεί τον destructor και απελευθερώνει τη μνήμη - [ ] Β. Ο destructor καλεί τον τελεστή delete και απελευθερώνει τη μνήμη - [ ] Γ. Ο destructor απελευθερώνει τη μνήμη - [ ] Δ. Ο destructor καλεί τον τελεστή delete και η μνήμη παραμένει δεσμευμένη
v. Ποιο είναι σωστό από τα παρακάτω: - [ ] Α. Κάθε κλάση έχει vTable - [ ] Β. vptr είναι ένας δείκτης για το vTable - [ ] Γ. Κάθε αντικείμενο έχει vptr - [ ] Δ. Όλα τα παραπάνω
ΘΕΜΑ 6ο (1,5 μονάδα): Απαντήστε στις παρακάτω ερωτήσεις δίνοντας σύντομη εξήγηση στο χώρο που δίνεται.
i. Έστω κλάση time με πεδία int hour, minute, second. Ποιος είναι ο προτιμώμενος constructor για την αρχικοποίηση των πεδίων σε 0; - [ ] Α. Time::Time() : hour( 0 ), minute( 0 ), second( 0 ) { }; - [ ] Β. Time::Time() : hour( 0 ), minute( 0 ) { second = 0 }; - [ ] Γ. Time::Time(int a=0, int b=0, int c=0){ }; - [ ] Δ. Ο 1ος και ο 2ος
ii. Τι θα τυπώσει ο παρακάτω κώδικας;
#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Constructor\n"; }
~Resource() { std::cout << "Destructor\n"; }
};
int main() {
Resource* res = new Resource();
return 0;
}
- [ ] a. Constructor Destructor
- [ ] b. Constructor
- [ ] c. Destructor
- [ ] d. Τίποτα από τα παραπάνω
3/4
Λύσεις (⚪ AI, μη επαληθευμένο)
Κατάσταση: ⚪ AI, μη επαληθευμένο Πηγή: migrated from previous_exams.md (Antigravity, 2026-10)
Προσοχή
Θέμα 3: η εκφώνηση του θέματος ζητά την κλάση Book, ενώ ο κώδικας της main χρησιμοποιεί την κλάση Student. Η λύση υλοποιεί την Student. Επιπλέον, η λύση δίνει έτος 1 όπου το αναμενόμενο αποτέλεσμα της εκφώνησης είναι «Year: -1». Δεν επαληθεύτηκε. Θέμα 2 (β): η λύση αφορά παραλλαγή του κώδικα (count = 0, χωρίς increment). Το συμπέρασμα (σφάλμα μεταγλώττισης, επειδή το private πεδίο είναι προσβάσιμο μόνο μέσα στην κλάση) ισχύει και για τον κώδικα του θέματος, αλλά η λύση δεν εξετάζει τον ακριβή κώδικα. Θέμα 4: η λύση εκτυπώνει το μήνυμα «Invalid index» και ελέγχει αρνητικό δείκτη. Η εκφώνηση δεν ζητά ούτε το μήνυμα ούτε τον αρνητικό δείκτη. Θέμα 5 (v): η λύση σημειώνει ως σωστή την επιλογή Β. Στη μεταγραφή όμως και η Α (κάθε κλάση έχει vTable) και η Γ (κάθε αντικείμενο έχει vptr) είναι σωστές, άρα η σωστή απάντηση είναι η Δ («Όλα τα παραπάνω»). Η σήμανση χρειάζεται επανέλεγχο. Θέμα 6 (i): η διατύπωση των επιλογών της λύσης διαφέρει από τη μεταγραφή (στη μεταγραφή η Δ είναι «Ο 1ος και ο 2ος»). Η απάντηση Α συμφωνεί με την επιλογή Α της μεταγραφής.
Λύσεις — Αντικειμενοστρεφής Προγραμματισμός — Σεπτέμβριος 2025¶
Οι λύσεις προέρχονται από το παλιό previous_exams.md. Οι εκφωνήσεις του παλιού αρχείου παραλείφθηκαν. Η εκφώνηση είναι αυτή του 2025-09.md.
Ερώτημα 1.a (Queue FIFO με LinkedList)¶
Λύση & Αιτιολόγηση:
1. Η διεπαφή Queue ακολουθεί τη λογική First-In-First-Out (FIFO - Πρώτο μέσα, πρώτο έξω).
2. Στοιχεία εισάγονται με τη σειρά: "C", μετά "B", μετά "A".
3. Η μέθοδος remove() αφαιρεί και επιστρέφει το στοιχείο που βρίσκεται στην κορυφή/αρχή (head) της ουράς.
- 1ο remove(): επιστρέφει "C".
- 2ο remove(): επιστρέφει "B".
Έξοδος:
C
B
Ερώτημα 1.b (Μοναδικότητα στοιχείων σε HashSet)¶
Λύση & Αιτιολόγηση:
1. Το Set δεν επιτρέπει διπλότυπα στοιχεία (duplicate elements).
2. Το στοιχείο 5 προστίθεται την 1η φορά, ενώ η 2η προσθήκη του απορρίπτεται σιωπηρά.
3. Τα μοναδικά στοιχεία του συνόλου είναι: {5, 10, 15}.
4. Το μέγεθος (size()) είναι \(3\).
Έξοδος:
3
Ερώτημα 1.c (Σύγκριση Αντικειμένων String: == vs .equals())¶
Λύση & Αιτιολόγηση:
1. Ο τελεστής == στα αντικείμενα Java συγκρίνει διευθύνσεις μνήμης (αναφορές / references):
- Το s1 είναι literal και τοποθετείται στο String Constant Pool.
- Το s2 δημιουργείται ρητά με new String(...) και τοποθετείται σε νέα ξεχωριστή θέση μνήμης στο Heap.
- Επομένως s1 == s2 επιστρέφει false.
2. Η μέθοδος .equals() συγκρίνει το περιεχόμενο (lexicographical value) των συμβολοσειρών:
- Και τα δύο αντικείμενα περιέχουν την ακολουθία χαρακτήρων "Hello".
- Επομένως s1.equals(s2) επιστρέφει true.
Έξοδος:
false
true
Ερώτημα 1.d (Έλεγχος Ροής με continue και break)¶
Λύση & Αιτιολόγηση:
Βήμα-βήμα εκτέλεση του loop:
- \(i=0\): \(sum = 0 + 0 = 0\)
- \(i=1\): \(sum = 0 + 1 = 1\)
- \(i=2\): i == 2 \(\implies\) εκτελείται continue (προσπερνάται η πρόσθεση, πάει στο επόμενο \(i\))
- \(i=3\): \(sum = 1 + 3 = 4\)
- \(i=4\): i == 4 \(\implies\) εκτελείται break (άμεση έξοδος από το loop)
Έξοδος:
4
🔹 Θέμα 2ο (2 Μονάδες) — Java Snippets & Concepts¶
Ερώτημα 2.a (Λειτουργία LIFO με Stack)¶
Λύση & Αιτιολόγηση:
Η στοίβα λειτουργεί με LIFO (Last-In-First-Out):
- \(i=3\): push(3), push(4), pop() $ o$ αφαιρείται και εκτυπώνεται το \(4\). (Στη στοίβα μένει: [3])
- \(i=2\): push(2), push(3), pop() $ o$ αφαιρείται και εκτυπώνεται το \(3\). (Στη στοίβα μένει: [3, 2])
- \(i=1\): push(1), push(2), pop() $ o$ αφαιρείται και εκτυπώνεται το \(2\). (Στη στοίβα μένει: [3, 2, 1])
Έξοδος:
4 3 2
Ερώτημα 2.b (Εμβέλεια και Ενθυλάκωση / Encapsulation)¶
Λύση & Αιτιολόγηση:
- Το πεδίο count δηλώνεται με access modifier private.
- Σύμφωνα με τους κανόνες ενθυλάκωσης της Java, τα private πεδία είναι προσπελάσιμα αποκλειστικά εντός του σώματος της ίδιας της κλάσης Counter.
- Η κλάση Test προσπαθεί να διαβάσει άμεσα το c.count, γεγονός που προκαλεί Compile-time Error (count has private access in Counter).
Ερώτημα 2.c (Default Values Πινάκων στην Java)¶
Λύση & Αιτιολόγηση:
- Στην Java, όταν δεσμεύεται πίνακας με πρωταρχικούς τύπους (primitives), όλα τα στοιχεία του αρχικοποιούνται αυτόματα στις default τιμές τους.
- Για τον τύπο boolean, η default τιμή είναι false (για αριθμητικούς είναι 0 / 0.0, για αναφορές αντικειμένων είναι null).
Έξοδος:
false
Ερώτημα 2.d (Σύγκριση Αναφορών Αντικειμένων)¶
Λύση & Αιτιολόγηση:
- Οι αναφορές e1 και e2 δείχνουν σε δύο εντελώς διαφορετικές παρουσίες (instances) αντικειμένων στη μνήμη σωρού (heap), καθώς καθεμία δημιουργήθηκε με ξεχωριστή κλήση του τελεστή new.
- Ο τελεστής == ελέγχει αν δύο μεταβλητές αναφέρονται στο ίδιο φυσικό αντικείμενο (e1 == e2). Εφόσον οι διευθύνσεις μνήμης διαφέρουν, επιστρέφει false.
Έξοδος:
false
🔹 Θέμα 3ο (2 Μονάδες) — Σχεδίαση Κλάσης & Constructor Chaining σε Java¶
Πλήρης Υλοποίηση σε Java:
public class Student {
// Ιδιωτικά πεδία (Encapsulation)
private String name;
private String id;
private int year;
// 1ος Constructor: Μόνο όνομα
public Student(String name) {
// Κλήση του 2ου constructor με προεπιλεγμένο id = -1
this(name, -1);
}
// 2ος Constructor: Όνομα και ID
public Student(String name, int id) {
// Κλήση του βασικού/πλήρους 3ου constructor με προεπιλεγμένο year = 1
this(name, id, 1);
}
// 3ος Constructor (Master/Canonical): Όλα τα πεδία
public Student(String name, int id, int year) {
this.name = name;
this.id = (id == -1) ? "Unknown" : String.valueOf(id);
this.year = year;
}
// Μέθοδος εμφάνισης στοιχείων
public void display() {
System.out.println("Student Information:");
System.out.println(" Name : " + this.name);
System.out.println(" ID : " + this.id);
System.out.println(" Year : " + ((this.year <= 0) ? "N/A" : this.year));
}
// Μέθοδος δοκιμής (main)
public static void main(String[] args) {
Student s1 = new Student("Nikos");
Student s2 = new Student("Maria", 1092345);
Student s3 = new Student("Giannis", 1087654, 3);
s1.display();
s2.display();
s3.display();
}
}
🔹 Θέμα 4ο (1,5 Μονάδες) — Διαχείριση Εξαιρέσεων σε Java¶
Πλήρης Υλοποίηση σε Java:
public class ArrayExceptionHandling {
public static void setValue(int[] arr, int index, int value) {
try {
arr[index] = value;
System.out.println("Successfully set arr[" + index + "] = " + value);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid index: " + index);
}
}
public static void main(String[] args) {
int[] myArray = new int[10];
// Έγκυρη τοποθέτηση
setValue(myArray, 5, 42);
// Άκυρη τοποθέτηση (εκτός ορίων [0..9])
setValue(myArray, 15, 99);
// Άκυρη τοποθέτηση (αρνητικός δείκτης)
setValue(myArray, -1, 10);
}
}
🔹 Θέμα 5ο (1 Μονάδα) — Ερωτήσεις Πολλαπλής Επιλογής C++¶
Ερώτηση i:
- Γ. Τα πρότυπα (Templates) (Σωστό)
Αιτιολόγηση: Τα template <typename T> της C++ επιτρέπουν τη συγγραφή γενικών συναρτήσεων και κλάσεων ανεξάρτητων από τον συγκεκριμένο τύπο δεδομένων.
Ερώτηση ii:
- Γ. Ο συνδέτης (Linker) (Σωστό)
Αιτιολόγηση: Ο Linker αναλαμβάνει να συνδέσει τα παραγόμενα object files (.o / .obj) και τις βιβλιοθήκες (.lib / .a / .so) για τη δημιουργία του τελικού εκτελέσιμου αρχείου.
Ερώτηση iii:
- Α. Το αριστερό μέλος του τελεστή είναι το αντικείμενο για το οποίο καλείται η μέθοδος (
*this) (Σωστό)
Αιτιολόγηση: Σε μέλος κλάσης a + b, η έκφραση ισοδυναμεί με a.operator+(b). Το αριστερό αντικείμενο a περνάει αυτόματα μέσω του δείκτη this.
Ερώτηση iv:
- Α. Ο τελεστής
deleteκαλεί τον destructor και αποδεσμεύει τη μνήμη (Σωστό)
Αιτιολόγηση: Ο delete ptr καλεί πρώτα τον αποδομητή (destructor) του αντικειμένου και στη συνέχεια επιστρέφει το μπλοκ μνήμης στο λειτουργικό σύστημα.
Ερώτηση v:
- Β. Ο vptr (vpointer) είναι δείκτης που περιέχεται σε κάθε αντικείμενο και δείχνει στον vTable της κλάσης του (Σωστό)
Αιτιολόγηση: Κάθε αντικείμενο πολυμορφικής κλάσης περιέχει έναν κρυφό δείκτη vptr, ο οποίος δείχνει στον μοναδικό ανά κλάση πίνακα εικονικών μεθόδων (vTable).
🔹 Θέμα 6ο (1,5 Μονάδες) — C++ Constructors & Memory Deallocation¶
Ερώτημα 6.i (Member Initializer List)¶
- Α.
Time::Time() : hour(0), minute(0), second(0) {}(Σωστό)
Αιτιολόγηση: Η λίστα αρχικοποίησης μελών (member initializer list) αρχικοποιεί τα μέλη απευθείας κατά την κατασκευή τους, αποτρέποντας διπλή εργασία (προεπιλεγμένη κατασκευή και κατόπιν εκχώρηση τιμής), κάτι που είναι επιβεβλημένο για αναφορές (&), const μέλη και κλάσεις χωρίς default constructor.
Ερώτημα 6.ii (Εκτέλεση Destructor και Διαρροή Μνήμης)¶
- b.
Constructor(Σωστό) - c.
Destructor - d. Δεν εκτυπώνεται τίποτα (Segmentation fault)
Λύση & Αιτιολόγηση:
1. Το αντικείμενο δεσμεύεται δυναμικά στο Heap με τον τελεστή new Resource(). Εκτελείται ο κατασκευαστής, τυπώνοντας "Constructor ".
2. Το πρόγραμμα τερματίζει με return 0 χωρίς να κληθεί ποτέ ο τελεστής delete res.
3. Στη C++ δεν υπάρχει Garbage Collector. Εφόσον δεν καλείται ρητά delete, ο αποδομητής (destructor) δεν εκτελείται ποτέ (Memory Leak).
4. Επομένως, εκτυπώνεται μόνο:
Constructor