Λύσεις — Κεφάλαιο 11: Αντικειμενοστρεφής Προγραμματισμός (σελ. 202-224) – ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ Γ΄ ΕΠΑΛ

Λύσεις — Κεφάλαιο 11: Αντικειμενοστρεφής Προγραμματισμός (σελ. 202-224)

Λύσεις των δύο Δραστηριοτήτων εμπέδωσης (κλάση Car· Person/Student/Teacher), των 3 Δραστηριοτήτων του κεφαλαίου (Akeraios, Student, σύνοψη όρων) και των 8 Ερωτήσεων, ελεγμένες με το επίσημο βιβλίο λύσεων.


Δραστηριότητα εμπέδωσης παραγράφου 11.2 — Η κλάση Car (7 ερωτήματα)

Ερώτηση: Δίνεται η κλάση Car (def init(self, make): self.make = make; self.speed = 60 / def speed_up(self, speed): self.speed = speed; print 'I am driving at a speed', self.speed, 'km/h' / def turn(self): print 'I am turning …'). 1. Ποιος είναι ο κατασκευαστής της κλάσης; 2. Να καταγράψετε τις ιδιότητες της κλάσης, τις μεθόδους της, καθώς και τις ενέργειες που πραγματοποιούν. 3. Να προσθέσετε τις ιδιότητες color και year (χρώμα, έτος κυκλοφορίας) που θα αρχικοποιούνται στον κατασκευαστή. 4. Να αλλάξετε τη μέθοδο turn ώστε να δέχεται ως παράμετρο μια συμβολοσειρά που ορίζει αν το αυτοκίνητο θα στρίψει αριστερά ή δεξιά. 5. Να δημιουργήσετε τα στιγμιότυπα: convertible (bmw, μαύρο, 2013) και sedan (toyota, κόκκινο, 2009). 6. Να καλέσετε την κατάλληλη μέθοδο ώστε το convertible να στρίψει δεξιά. 7. Να καλέσετε την κατάλληλη μέθοδο ώστε το sedan να τρέχει με 90 χιλ/ώρα.

Απάντηση:

  • 1. Κατασκευαστής: η μέθοδος __init__(self, make) — καλείται αυτόματα σε κάθε δημιουργία αντικειμένου Car, δημιουργεί το αντικείμενο και αρχικοποιεί τις ιδιότητές του (make από την παράμετρο, speed = 60).

  • 2. Ιδιότητες: make (μάρκα) και speed (ταχύτητα, αρχική τιμή 60). Μέθοδοι:speed_up(self, speed) — δίνει στην ιδιότητα speed τη νέα τιμή και εμφανίζει «I am driving at a speed», την τιμή της ταχύτητας και «km/h»· ② turn(self) — εμφανίζει το μήνυμα «I am turning …» (δεν αλλάζει ιδιότητες). (Και η init είναι μέθοδος — ο κατασκευαστής.)

  • 3-4. Νέα έκδοση της κλάσης με τις ιδιότητες color, year στον κατασκευαστή και την turn με παράμετρο κατεύθυνσης· 5-7. στιγμιότυπα και κλήσεις:

  • # -*- coding: utf-8 -*-
    class Car:
        def __init__(self, make, color, year):     # 3. νέες ιδιότητες στον κατασκευαστή
            self.make = make
            self.color = color
            self.year = year
            self.speed = 60
        def speed_up(self, speed):
            self.speed = speed
            print "I am driving at a speed", self.speed, "km/h"
        def turn(self, direction):                 # 4. παράμετρος 'αριστερά' / 'δεξιά'
            print "I am turning", direction
    
    convertible = Car("bmw", "μαύρο", "2013")      # 5.I
    sedan = Car("toyota", "κόκκινο", "2009")       # 5.II
    convertible.turn("δεξιά")                      # 6. -> I am turning δεξιά
    sedan.speed_up(90)                             # 7. -> I am driving at a speed 90 km/h
  • Οι ιδιότητες ορίζονται με self.όνομα = τιμή μέσα στην init (καλή πρακτική: όλες εκεί), τα στιγμιότυπα δημιουργούνται καλώντας την κλάση με τα ορίσματα του κατασκευαστή (χωρίς το self), και οι μέθοδοι καλούνται με dot notation αντικείμενο.μέθοδος(ορίσματα). Το έτος μπορεί να δοθεί και ως ακέραιος (2013). Η επίσημη λύση γράφει τις κλήσεις ως convertible.turn('right') και sedan.speed_up(90) — ταυτόσημη λογική.

Σύνοψη: 1. init(self, make). 2. Ιδιότητες make, speed· μέθοδοι speed_up (θέτει ταχύτητα και τυπώνει μήνυμα), turn (τυπώνει μήνυμα). 3. init(self, make, color, year) με self.color, self.year. 4. def turn(self, direction): print 'I am turning', direction. 5. convertible = Car('bmw','μαύρο','2013'), sedan = Car('toyota','κόκκινο','2009'). 6. convertible.turn('δεξιά'). 7. sedan.speed_up(90).

Κριτήρια αξιολόγησης:

  • Και τα επτά ερωτήματα, με σωστή σύνταξη κλάσης/κλήσεων.

Δραστηριότητα εμπέδωσης ενότητας 11.3.1 — Οι κλάσεις Person, Student, Teacher (5 ερωτήματα)

Ερώτηση: Δίνονται οι κλάσεις Person(object) με init(self, name): self._name = name, και Student(Person) με init(self, name, classatt): super(Student, self).init(name); self.classatt = classatt. Ποιες είναι οι ιδιότητες της κλάσης Student; Δημιουργήστε στιγμιότυπο της κλάσης Student με όνομα Γιάννης και τάξη Β. Πώς θα εμφανίσετε τις ιδιότητες του στιγμιότυπου που δημιουργήσατε; Να ορίσετε υποκλάση Teacher της κλάσης Person, η οποία εκτός από το όνομα θα έχει επιπλέον τις ιδιότητες κλάδος (field) και χρόνια υπηρεσίας (years). Δημιουργήστε τα στιγμιότυπα της Teacher: Αναστασίου, ΠΕ02, 11 και Παπαχρήστου, ΠΕ03, 16.

Απάντηση:

  • Ιδιότητες της Student: _name (την κληρονομεί από την υπερκλάση Person — ορίζεται στον κατασκευαστή της Person, που καλείται με super(Student, self).__init__(name)) και classatt (η τάξη, δική της ιδιότητα). Άρα κάθε μαθητής έχει όνομα και τάξη.

  • # -*- coding: utf-8 -*-
    class Person(object):
        def __init__(self, name):
            self._name = name
    
    class Student(Person):
        def __init__(self, name, classatt):
            super(Student, self).__init__(name)     # κλήση του κατασκευαστή της Person
            self.classatt = classatt
    
    class Teacher(Person):                          # υποκλάση της Person
        def __init__(self, name, field, years):
            super(Teacher, self).__init__(name)     # το όνομα το αναλαμβάνει η Person
            self.field = field                      # κλάδος
            self.years = years                      # χρόνια υπηρεσίας
    
    student1 = Student("Γιάννης", "Β")              # στιγμιότυπο της Student
    print student1._name                           # εμφάνιση των ιδιοτήτων -> Γιάννης
    print student1.classatt                        #                         -> Β
    
    teacher1 = Teacher("Αναστασίου", "ΠΕ02", 11)
    teacher2 = Teacher("Παπαχρήστου", "ΠΕ03", 16)
    print teacher1._name, teacher1.field, teacher1.years   # Αναστασίου ΠΕ02 11
  • Εξήγηση: η Teacher ορίζεται με class Teacher(Person): — κληρονομεί το _name και προσθέτει field, years· ο κατασκευαστής της καλεί τον κατασκευαστή της Person με super (δυνατό επειδή η Person κληρονομεί από την object) και μετά αρχικοποιεί τις δικές της ιδιότητες. Οι ιδιότητες εμφανίζονται με dot notation (student1._name, student1.classatt). Το _name με μία κάτω παύλα δηλώνει, κατά σύμβαση, «εσωτερική» ιδιότητα — παρ' όλα αυτά είναι προσπελάσιμη. Τα χρόνια υπηρεσίας μπορούν να δοθούν ως ακέραιοι (11, 16) ή, όπως στην εκφώνηση, ως συμβολοσειρές.

Σύνοψη: Ιδιότητες Student: _name (κληρονομημένη από Person) και classatt· student1 = Student('Γιάννης', 'Β')· print student1._name, print student1.classatt· class Teacher(Person) με init(self, name, field, years): super(Teacher, self).init(name); self.field = field; self.years = years· teacher1 = Teacher('Αναστασίου', 'ΠΕ02', 11), teacher2 = Teacher('Παπαχρήστου', 'ΠΕ03', 16).

Κριτήρια αξιολόγησης:

  • Και τα πέντε ερωτήματα, με super στον κατασκευαστή της Teacher.

Δραστηριότητα 1 — Η κλάση Akeraios με Anathese_timi και Emfanise_timi

Ερώτηση: Να ορίσετε κλάση με όνομα Akeraios, η οποία θα έχει την ιδιότητα timi και τις παρακάτω μεθόδους: I. Anathese_timi(timi), η οποία θα αναθέτει τιμή στην ιδιότητα του αντικειμένου. II. Emfanise_timi(), η οποία θα εμφανίζει την τιμή της ιδιότητας του αντικειμένου. Στη συνέχεια να δημιουργήσετε στιγμιότυπο της κλάσης Akeraios με όνομα Artios και να χρησιμοποιήσετε τις παραπάνω μεθόδους για να δώσετε την τιμή 14 στην ιδιότητα του αντικειμένου και να την εμφανίσετε.

Απάντηση:

  • class Akeraios:
        def __init__(self):
            self.timi = 0                  # αρχικοποίηση της ιδιότητας στον κατασκευαστή
        def Anathese_timi(self, timi):     # μέθοδος ανάθεσης τιμής (set)
            self.timi = timi
        def Emfanise_timi(self):           # μέθοδος εμφάνισης τιμής
            print self.timi
    
    Artios = Akeraios()                    # στιγμιότυπο της κλάσης
    Artios.Anathese_timi(14)               # ανάθεση της τιμής 14
    Artios.Emfanise_timi()                 # εμφάνιση -> 14
  • Εξήγηση: η ιδιότητα timi αρχικοποιείται στον κατασκευαστή (σωστή πρακτική, σελ. 200-202) — ο κατασκευαστής εδώ δεν χρειάζεται άλλη παράμετρο εκτός από το self. Η Anathese_timi είναι μέθοδος τύπου set (δίνει τιμή στην ιδιότητα μέσω του self.timi) και η Emfanise_timi τύπου εμφάνισης/get — έτσι η πρόσβαση στην ιδιότητα γίνεται μέσω μεθόδων (ενθυλάκωση). Το αντικείμενο Artios δημιουργείται καλώντας την κλάση χωρίς ορίσματα και οι μέθοδοι καλούνται με dot notation. Έξοδος: 14. Συμφωνεί με την επίσημη λύση (σελ. 116).

Σύνοψη: class Akeraios με init (self.timi = 0), Anathese_timi(self, timi): self.timi = timi, Emfanise_timi(self): print self.timi· Artios = Akeraios()· Artios.Anathese_timi(14)· Artios.Emfanise_timi() → 14.

Κριτήρια αξιολόγησης:

  • Κλάση με τις δύο μεθόδους + στιγμιότυπο + κλήσεις.

Δραστηριότητα 2 — Η κλάση Student (ΑΜ, ονοματεπώνυμο, 8 βαθμοί, μέσος όρος)

Ερώτηση: Να ορίσετε κλάση με όνομα Student η οποία θα έχει τρεις ιδιότητες για τον αριθμό μητρώου, το ονοματεπώνυμο και τους βαθμούς σε 8 μαθήματα (πίνακας). Επίσης να ορίσετε τις μεθόδους: I. Μια μέθοδο για την ανάθεση τιμών στις ιδιότητες ενός αντικειμένου. II. Μια μέθοδο για την εμφάνιση των τιμών των ιδιοτήτων ενός αντικειμένου. III. Μια μέθοδο για τον υπολογισμό και την επιστροφή του μέσου όρου βαθμολογίας στα 8 μαθήματα. Στη συνέχεια να ορίσετε ένα στιγμιότυπο της κλάσης Student με όνομα Chris και να χρησιμοποιήσετε τις παραπάνω μεθόδους για να δώσετε τιμή στις ιδιότητες του αντικειμένου, να τις εμφανίσετε και να υπολογίσετε το μέσο όρο βαθμολογίας του.

Απάντηση:

  • Οι τρεις ιδιότητες (AM, name, grades — λίστα 8 βαθμών) αρχικοποιούνται στον κατασκευαστή με ουδέτερες τιμές· η μέθοδος ανάθεσης τις γεμίζει, η μέθοδος εμφάνισης τις τυπώνει και η τρίτη διασχίζει τη λίστα των βαθμών, αθροίζει και επιστρέφει τον μέσο όρο (άθροισμα πραγματικό για να μη γίνει ακέραια διαίρεση στην Python 2):

  • class Student:
        def __init__(self):
            self.AM = 0                         # αριθμός μητρώου
            self.name = ''                      # ονοματεπώνυμο
            self.grades = []                    # βαθμοί σε 8 μαθήματα (λίστα)
        def Anathese_times(self, AM, name, grades):      # I. ανάθεση τιμών
            self.AM = AM
            self.name = name
            self.grades = grades[:8]            # αντίγραφο των 8 πρώτων βαθμών
        def Emfanise_times(self):                        # II. εμφάνιση τιμών
            print "AM:", self.AM
            print "Name:", self.name
            print "Grades:", self.grades
        def Ypol_MO(self):                               # III. μέσος όρος
            sum = 0.0                           # πραγματικός, ώστε η διαίρεση να μην είναι ακέραια
            for grade in self.grades:
                sum = sum + grade
            return sum / len(self.grades)
    
    Chris = Student()
    Chris.Anathese_times(209, "Chris Papadopoulos", [14, 16, 18, 19, 12, 20, 17, 20])
    Chris.Emfanise_times()
    print "Mesos oros:", Chris.Ypol_MO()      # -> 17.0
  • Έξοδος: AM: 209 / Name: Chris Papadopoulos / Grades: [14, 16, 18, 19, 12, 20, 17, 20] / Mesos oros: 17.0 (άθροισμα 136 / 8). Η επίσημη λύση (σελ. 117) δίνει τις τιμές απευθείας στον κατασκευαστή Student(AM, name, grades) αντί για ξεχωριστή μέθοδο ανάθεσης — και οι δύο προσεγγίσεις είναι αποδεκτές, αρκεί να υπάρχουν οι τρεις ζητούμενες μέθοδοι· με sum = 0 (ακέραιο) η επίσημη λύση θα έδινε 17 αντί 17.0, και για βαθμούς με μη ακέραιο μέσο όρο θα έκοβε τα δεκαδικά — γι' αυτό το 0.0.

Σύνοψη: class Student με ιδιότητες AM, name, grades (λίστα)· Anathese_times(AM, name, grades), Emfanise_times() (print), Ypol_MO() (άθροισμα 0.0 / len → return)· Chris = Student(); Chris.Anathese_times(209, 'Chris', [8 βαθμοί]); Chris.Emfanise_times(); print Chris.Ypol_MO() → 17.0.

Κριτήρια αξιολόγησης:

  • Τρεις ιδιότητες + τρεις μέθοδοι (η τρίτη με return) + στιγμιότυπο και κλήσεις.

Δραστηριότητα 3 — Συζήτηση, συμπλήρωση και επέκταση της σύνοψης βασικών όρων του κεφαλαίου

Ερώτηση: Συζητήστε, συμπληρώστε ή επεκτείνετε την παρακάτω σύνοψη βασικών όρων του κεφαλαίου: Αντικειμενοστρεφής προγραμματισμός, Κλάση, Αντικείμενο, Στιγμιότυπο μιας κλάσης, Ιδιότητα αντικειμένου, Μέθοδος, Κληρονομικότητα, Πολυμορφισμός, Ενθυλάκωση.

Απάντηση:

  • Οι όροι του βιβλίου (σελ. 223), συμπληρωμένοι:Αντικειμενοστρεφής προγραμματισμός: τρόπος προγραμματισμού στον οποίο τα δεδομένα και οι λειτουργίες είναι οργανωμένα σε αντικείμενα — η εστίαση μεταφέρεται από τις διαδικασίες στις έννοιες· η Python είναι στη βάση της αντικειμενοστρεφής (όλα είναι στιγμιότυπα κλάσεων).Κλάση: τύπος ορισμένος από τον χρήστη, «συνταγή» δημιουργίας αντικειμένων — ορίζεται με τη λέξη class, περιέχει τις ιδιότητες και τις μεθόδους που είναι κοινές στα αντικείμενά της και ενσωματώνει τον κατασκευαστή.Αντικείμενο: δομή δεδομένων και επεξεργαστική ενότητα που δημιουργήθηκε βάσει κλάσης — περιγράφει μια οντότητα της πραγματικής ζωής με ιδιότητες και μεθόδους.Στιγμιότυπο: αντικείμενο που δημιουργήθηκε από συγκεκριμένη κλάση — mybeetle = Vehicle('yellow', 2000.00, 4, 80)· πολλά στιγμιότυπα από την ίδια κλάση, με διαφορετικές τιμές.Ιδιότητα αντικειμένου: μία από τις μεταβλητές που σχετίζονται με ένα αντικείμενο — προσπέλαση με dot notation (αντικείμενο.ιδιότητα)· διακρίνονται ιδιότητες κλάσης (κοινές) και στιγμιοτύπου.Μέθοδος: συνάρτηση ορισμένη μέσα σε κλάση, που χρησιμοποιείται από τα στιγμιότυπά της — πρώτη παράμετρος το self· κλήση αντικείμενο.μέθοδος()· υπογραφή = όνομα, ορίσματα, τιμή επιστροφής.
  • Κληρονομικότητα: μεταφορά χαρακτηριστικών μιας κλάσης σε υποκλάσεις που προέρχονται ρητά από αυτήν· οι υποκλάσεις επαναχρησιμοποιούν τις μεταβιβάσιμες μεθόδους/ιδιότητες και προσθέτουν δικές τους — υπερκλάση/βασική → υποκλάση/παράγωγη, σχέση is-a, ιεραρχία γενικό → ειδικό, σύνταξη class Υποκλάση(Υπερκλάση), κλήση κατασκευαστή γονέα με super· το σημαντικότερο χαρακτηριστικό (επαναχρησιμοποίηση, αξιοπιστία).Πολυμορφισμός: η δυνατότητα των μεταγλωττιστών/διερμηνευτών να αποφασίζουν δυναμικά ποια από τις ομώνυμες μεθόδους θα κληθεί, ανάλογα με το αντικείμενο ή τον τύπο/αριθμό των παραμέτρων — π.χ. ο τελεστής + για αριθμούς (πρόσθεση) και συμβολοσειρές (συνένωση), ή η ίδια μέθοδος «μεταφέρω» σε επιβατικό, φορτηγό, λεωφορείο.Ενθυλάκωση: η ιδιότητα των κλάσεων να «κρύβουν» τα ιδιωτικά δεδομένα τους και να επιτρέπουν πρόσβαση μόνο μέσω των δημόσιων μεθόδων — δύο χαρακτηριστικά: θύλακας δεδομένων + μεθόδων και απόκρυψη πληροφορίας (interface vs υλοποίηση)· πλεονεκτήματα έλεγχος και ευκολία αλλαγών· τροποποιητές public/private/protected, μέθοδοι get/set, στην Python σύμβαση της διπλής κάτω παύλας.
  • Επέκταση με όρους που λείπουν από τη σύνοψη:Κατασκευαστής (constructor): η ειδική μέθοδος init που καλείται αυτόματα στη δημιουργία αντικειμένου και αρχικοποιεί τις ιδιότητές του (αρχικοποίησηαποδομητής (destructor): καταστρέφει το αντικείμενο και απελευθερώνει τη μνήμη. • self: παράμετρος (σύμβαση, όχι δεσμευμένη λέξη) που αναφέρεται στο αντικείμενο που καλεί τη μέθοδο. • Στατική μέθοδος (@staticmethod): μέθοδος χωρίς self — συνάρτηση μέσα στην κλάση· μέθοδος κλάσης (@classmethod, cls): κληρονομήσιμη, π.χ. για καταμέτρηση στιγμιοτύπων. • Διεπαφή (interface) κλάσης: το σύνολο των δημόσιων λειτουργιών της (τι κάνει, όχι πώς). • Γεγονός / μήνυμα / χειριστής γεγονότος: εξωτερικό συμβάν (κλικ, πλήκτρο) → δεδομένα που προκαλούν προγραμματισμένη αντίδραση → η συνάρτηση που την υλοποιεί· διανεμητής (dispatcher) και μοντέλο παρατηρητή/ηθοποιού (εγγραφή χειριστών, χρήση στα GUI, bind της Tkinter). • Προγραμματισμός οδηγούμενος από γεγονότα: η συμπεριφορά των αντικειμένων καθορίζεται από γεγονότα και τους χειριστές τους.

Σύνοψη: (ενδεικτική) Οι εννέα όροι της σύνοψης (ΑΠ, κλάση, αντικείμενο, στιγμιότυπο, ιδιότητα, μέθοδος, κληρονομικότητα, πολυμορφισμός, ενθυλάκωση) με συμπληρώσεις από τη θεωρία (class, self, dot notation, super, is-a, get/set, δημόσια διεπαφή) και επέκταση: κατασκευαστής/init, αποδομητής, self, στατικές μέθοδοι/μέθοδοι κλάσης, διεπαφή, γεγονός/μήνυμα/χειριστής, διανεμητής, μοντέλο παρατηρητή.

Κριτήρια αξιολόγησης:

  • Οι όροι του βιβλίου με συμπλήρωση + τουλάχιστον τέσσερις επιπλέον όροι.

Ερώτηση 1 — Βασικά χαρακτηριστικά του αντικειμενοστρεφούς προγραμματισμού

Ερώτηση: Ποια είναι τα βασικά χαρακτηριστικά του αντικειμενοστρεφούς προγραμματισμού;

Απάντηση:

  • Ο αντικειμενοστρεφής προγραμματισμός οργανώνει τα δεδομένα και τις λειτουργίες σε αντικείμενα, μεταφέροντας την εστίαση από τις διαδικασίες στις έννοιες (σελ. 193). Τα βασικά του χαρακτηριστικά:
  • Αντικείμενα και κλάσεις: κάθε οντότητα περιγράφεται ως αντικείμενο με ιδιότητες (δεδομένα) και μεθόδους (ενέργειες)· οι κλάσεις είναι τα πρότυπα («συνταγές») από τα οποία δημιουργούνται στιγμιότυπα μέσω του κατασκευαστή. • Κληρονομικότητα (inheritance): οι υποκλάσεις κληρονομούν ιδιότητες και μεθόδους από τις υπερκλάσεις και προσθέτουν δικές τους — ιεραρχίες κλάσεων και επαναχρησιμοποίηση κώδικα· το πιο σημαντικό χαρακτηριστικό (σελ. 208). • Πολυμορφισμός (polymorphism): ομώνυμες μέθοδοι συμπεριφέρονται διαφορετικά ανάλογα με το αντικείμενο που τις καλεί ή τις παραμέτρους· επιλογή δυναμικά από τον διερμηνευτή (σελ. 213). • Ενθυλάκωση (encapsulation) και απόκρυψη πληροφορίας: δεδομένα και μέθοδοι σε έναν θύλακα, με τα ιδιωτικά δεδομένα προσπελάσιμα μόνο μέσω δημόσιων μεθόδων (διεπαφή vs υλοποίηση, τροποποιητές πρόσβασης) (σελ. 213-216). • Οδήγηση από γεγονότα / μηνύματα: η συμπεριφορά των αντικειμένων καθορίζεται από γεγονότα και τους χειριστές τους (σελ. 217).
  • Αποτέλεσμα: ευκολότερη παρακολούθηση, διόρθωση και συντήρηση μεγάλων εφαρμογών, επαναχρησιμοποίηση και αξιοπιστία.

Σύνοψη: (ενδεικτική) Οργάνωση δεδομένων και λειτουργιών σε αντικείμενα (κλάσεις, στιγμιότυπα, ιδιότητες, μέθοδοι, κατασκευαστής)· κληρονομικότητα· πολυμορφισμός· ενθυλάκωση/απόκρυψη πληροφορίας· οδήγηση από γεγονότα — με όφελος την επαναχρησιμοποίηση και τη συντηρησιμότητα.

Κριτήρια αξιολόγησης:

  • Αντικείμενα/κλάσεις + τα τρία μεγάλα χαρακτηριστικά (+ γεγονότα).

Ερώτηση 2 — Διαφορά αντικειμενοστρεφούς από δομημένο προγραμματισμό

Ερώτηση: Σε τι διαφέρει ο αντικειμενοστρεφής από το δομημένο προγραμματισμό;

Απάντηση:

  • Δομημένος / διαδικαστικός προγραμματισμός: τα προγράμματα δομούνται με προτεραιότητα στις ενέργειες έναντι των δεδομένων — περιγράφουμε διαδικασίες και συναρτήσεις που επεξεργάζονται και τροποποιούν δεδομένα, και αυτές θεωρούνται τα δομικά στοιχεία· οι εφαρμογές αποτελούνται από ακολουθίες εντολών, επαναλήψεις, δομές ελέγχου και υποπρογράμματα (σελ. 192-193). Τα δεδομένα και οι λειτουργίες είναι χωριστά. Ιδιαίτερα λειτουργική προσέγγιση, αλλά όσο οι εφαρμογές μεγαλώνουν, η παρακολούθηση, η διόρθωση και η συντήρηση δυσκολεύουν.
  • Αντικειμενοστρεφής προγραμματισμός: αλλάζει την εστίαση από τις διαδικασίες στις έννοιες/οντότητες· σε αυτές αναθέτει ιδιότητες (τα δεδομένα) που επεξεργάζονται μέθοδοι — δεδομένα και λειτουργίες ενωμένα σε αντικείμενα, που δημιουργούνται από κλάσεις. Προσφέρει κληρονομικότητα (επαναχρησιμοποίηση), πολυμορφισμό και ενθυλάκωση (απόκρυψη υλοποίησης), και οδήγηση από γεγονότα. Εξυπηρετεί καλύτερα σε βάσεις δεδομένων, Τεχνητή Νοημοσύνη, γραφικά περιβάλλοντα και μεγάλες, πολύπλοκες εφαρμογές. Η Python υποστηρίζει και τα δύο, αλλά είναι στη βάση της αντικειμενοστρεφής.

Σύνοψη: (ενδεικτική) Δομημένος: προτεραιότητα στις ενέργειες, διαδικασίες/συναρτήσεις που επεξεργάζονται χωριστά δεδομένα (ακολουθία, επιλογή, επανάληψη, υποπρογράμματα), δύσκολη συντήρηση σε μεγάλες εφαρμογές. Αντικειμενοστρεφής: εστίαση στις έννοιες — δεδομένα (ιδιότητες) και λειτουργίες (μέθοδοι) μαζί σε αντικείμενα/κλάσεις, με κληρονομικότητα, πολυμορφισμό, ενθυλάκωση, γεγονότα.

Κριτήρια αξιολόγησης:

  • Οι δύο προσεγγίσεις σε αντιπαραβολή (εστίαση, οργάνωση δεδομένων/λειτουργιών, συντήρηση).

Ερώτηση 3 — Τι είναι η κλάση και τι το αντικείμενο (στιγμιότυπο)

Ερώτηση: Τι είναι η κλάση και τι το αντικείμενο (στιγμιότυπο) μιας κλάσης;

Απάντηση:

  • Κλάση: πρότυπο που συγκεντρώνει τα κοινά στοιχεία (ιδιότητες και μεθόδους) μιας κατηγορίας αντικειμένων — ένας τύπος ορισμένος από τον χρήστη, μια «συνταγή» δημιουργίας αντικειμένων (σελ. 195, 223). Μας επιτρέπει να γνωρίζουμε πράγματα για αντικείμενα που δεν έχουν δημιουργηθεί ακόμη· παρομοιάζεται με το σχέδιο ενός αυτοκινήτου ή το αρχιτεκτονικό σχέδιο σπιτιού. Στην Python ορίζεται με τη λέξη class και ενσωματώνει τον κατασκευαστή (init) και τις μεθόδους.
  • Αντικείμενο / στιγμιότυπο (instance): μια «πραγματική» υλοποίηση της κλάσης — δομή δεδομένων και επεξεργαστική ενότητα που δημιουργήθηκε βάσει της κλάσης, με συγκεκριμένες τιμές στις ιδιότητες (σελ. 198, 223). Δημιουργείται καλώντας την κλάση με ορίσματα για τον κατασκευαστή: mybeetle = Vehicle('yellow', 2000.00, 4, 80). Από την ίδια κλάση μπορούν να δημιουργηθούν πολλά διαφορετικά στιγμιότυπα.
  • Παράδειγμα της τάρτας (σελ. 196): η κλάση «τάρτα» είναι η συνταγή — όσο έχεις μόνο τη συνταγή δεν έχεις τάρτα να φας· το αντικείμενο τάρτα είναι μια πραγματική τάρτα φτιαγμένη με τη συνταγή, και μπορούν να υπάρχουν πολλές τάρτες από την ίδια συνταγή. Η ύπαρξη της κλάσης δεν συνεπάγεται ύπαρξη αντικειμένου.

Σύνοψη: (ενδεικτική) Κλάση = τύπος/πρότυπο («συνταγή») που ορίζει τις κοινές ιδιότητες και μεθόδους και τον κατασκευαστή· αντικείμενο/στιγμιότυπο = συγκεκριμένη υλοποίηση της κλάσης με δικές της τιμές, που δημιουργείται καλώντας την κλάση (πολλά ανά κλάση) — παράδειγμα συνταγή/τάρτα.

Κριτήρια αξιολόγησης:

  • Δύο ορισμοί + το παράδειγμα.

Ερώτηση 4 — Πώς δηλώνουμε μια κλάση στην Python

Ερώτηση: Πώς δηλώνουμε μια κλάση στην Python;

Απάντηση:

  • Ο ορισμός κλάσης μοιάζει με αυτόν μιας συνάρτησης, αλλά με τη λέξη-κλειδί class αντί για def: class Όνομα:class Όνομα(object): — καλή πρακτική για κλάσεις που δεν κληρονομούν από άλλη, ώστε να μπορούν οι υποκλάσεις να καλούν μεθόδους της με super· για υποκλάση class Όνομα(Υπερκλάση):). Στο σώμα της, σε εσοχή, ορίζονται: η init(self, …) — ο κατασκευαστής, όπου οι ιδιότητες παίρνουν τιμή με self.ιδιότητα = τιμή — και οι μέθοδοι, ως συναρτήσεις με πρώτη παράμετρο το self (σελ. 196-197):

  • class Vehicle:
        def __init__(self, color, price, wheels, speed):   # κατασκευαστής - ιδιότητες
            self.color = color
            self.price = price
            self.wheels = wheels
            self.speed = speed
        def accelerate(self, amount):                      # μέθοδος
            self.speed += amount
            return self.speed
        def decelerate(self, amount):
            self.speed -= amount
            return self.speed
    
    mybeetle = Vehicle('yellow', 2000.00, 4, 80)           # δημιουργία στιγμιοτύπου
    print mybeetle.accelerate(10)                          # -> 90
  • Το όνομα init έχει διπλές κάτω παύλες στην αρχή και στο τέλος· δεν καλείται ονομαστικά — καλείται αυτόματα όταν καλούμε την κλάση. Ιδιότητες κλάσης (κοινές) μπορούν να δηλωθούν και απευθείας στο σώμα (classattr = 'attr on class', σελ. 204).

Σύνοψη: class Όνομα: (ή class Όνομα(object): / class Όνομα(Υπερκλάση):) και σε εσοχή def init(self, παράμετροι): self.ιδιότητα = τιμή … + def μέθοδος(self, …): …· στιγμιότυπο με κλήση της κλάσης.

Κριτήρια αξιολόγησης:

  • Σύνταξη class + init με self + μέθοδοι· παράδειγμα.

Ερώτηση 5 — Κληρονομικότητα και πολυμορφισμός

Ερώτηση: Τι σημαίνει κληρονομικότητα και τι πολυμορφισμός;

Απάντηση:

  • Κληρονομικότητα (inheritance): η ιδιότητα των κλάσεων να μεταβιβάζουν τις ιδιότητες και τις μεθόδους τους σε νέες κλάσεις, που λέγονται κληρονόμοι ή υποκλάσεις (παράγωγες)· η αρχική είναι η βασική κλάση / υπερκλάση. Οι υποκλάσεις επαναχρησιμοποιούν τις μεταβιβάσιμες μεθόδους και ιδιότητες και προσθέτουν δικές τους (ή τις εξειδικεύουν) (σελ. 208). Χρησιμοποιείται όταν υπάρχει ιεραρχία από το γενικότερο στο ειδικότερο με σχέση is-a (το αυτοκίνητο είναι όχημα)· στιγμιότυπα υποκλάσης μπορούν να χρησιμοποιηθούν όπου ζητείται η υπερκλάση, όχι αντίστροφα. Στην Python: class Car(Vehicle):. Είναι το πιο σημαντικό χαρακτηριστικό του ΑΠ — επαναχρησιμοποίηση κώδικα, εξοικονόμηση χρόνου/χρήματος, αξιοπιστία.
  • Πολυμορφισμός (polymorphism): η δυνατότητα των αντικειμενοστρεφών μεταγλωττιστών/διερμηνευτών να αποφασίζουν δυναμικά ποια από τις ομώνυμες μεθόδους είναι κατάλληλη να κληθεί, ανάλογα με το αντικείμενο που την καλεί ή τον τύπο και τον αριθμό των παραμέτρων της (σελ. 213). Διαισθητικά: αντικείμενα διαφορετικών υποκλάσεων «κάνουν το ίδιο πράγμα με διαφορετικό τρόπο» — επιβατικό, φορτηγό, λεωφορείο μεταφέρουν, το καθένα αλλιώς (σελ. 196)· ο τελεστής + προσθέτει αριθμούς αλλά συνενώνει συμβολοσειρές (σελ. 108).

Σύνοψη: (ενδεικτική) Κληρονομικότητα = μεταβίβαση ιδιοτήτων/μεθόδων από υπερκλάση σε υποκλάσεις, που τις επαναχρησιμοποιούν και προσθέτουν δικές τους (ιεραρχία, is-a, class Υπο(Υπερ))· πολυμορφισμός = δυναμική επιλογή ποια από τις ομώνυμες μεθόδους θα κληθεί, ανάλογα με το αντικείμενο ή τις παραμέτρους (ίδια ενέργεια, διαφορετικός τρόπος).

Κριτήρια αξιολόγησης:

  • Δύο ορισμοί με παράδειγμα.

Ερώτηση 6 — Παράδειγμα κληρονομικότητας

Ερώτηση: Δώστε ένα παράδειγμα κληρονομικότητας.

Απάντηση:

  • Παράδειγμα από το βιβλίο (σελ. 209-210): η υπερκλάση Vehicle (Όχημα) με τις κοινές ιδιότητες (τροχοί, ταχύτητα, χρώμα, τιμή) και μεθόδους (accelerate, decelerate), και οι υποκλάσεις Car (Αυτοκίνητο) και Bicycle (Ποδήλατο) που τις κληρονομούν και προσθέτουν δικές τους· από την Car προκύπτουν οι Convertible και Sedan, από την Bicycle οι Βουνού, Πόλης, Διπλό — ιεραρχία «ανά γενιά». Αντίστοιχα Ζώο → Ψάρι, Έντομο, Θηλαστικό.

  • Σε κώδικα Python (κατά το παράδειγμα Person/Student της σελ. 212):

  • class Vehicle(object):                       # υπερκλάση (βασική κλάση)
        def __init__(self, color, speed):
            self.color = color
            self.speed = speed
        def accelerate(self, amount):
            self.speed += amount
            return self.speed
    
    class Car(Vehicle):                          # υποκλάση: κληρονομεί color, speed, accelerate
        def __init__(self, color, speed, doors):
            super(Car, self).__init__(color, speed)   # κλήση κατασκευαστή της υπερκλάσης
            self.doors = doors                   # νέα, δική της ιδιότητα
        def honk(self):                          # νέα, δική της μέθοδος
            print "Beep!"
    
    class Bicycle(Vehicle):
        def __init__(self, color, speed, gears):
            super(Bicycle, self).__init__(color, speed)
            self.gears = gears
    
    mycar = Car('red', 50, 5)
    print mycar.accelerate(30)                   # 80 - μέθοδος κληρονομημένη από τη Vehicle
    mycar.honk()                                 # Beep!
  • Η Car και η Bicycle δεν ξαναορίζουν την accelerate ούτε τα color/speed — τα κληρονομούν από τη Vehicle (επαναχρησιμοποίηση) και προσθέτουν μόνο ό,τι τους είναι ιδιαίτερο (doors/honk, gears). Η σχέση είναι is-a: ένα Car είναι Vehicle, οπότε ένα αντικείμενο Car μπορεί να χρησιμοποιηθεί όπου ζητείται Vehicle.

Σύνοψη: Όχημα (Vehicle) → Αυτοκίνητο (Car), Ποδήλατο (Bicycle) → Κλειστού τύπου, Ξεσκέπαστο: κοινές ιδιότητες/μέθοδοι στην υπερκλάση, οι υποκλάσεις (class Car(Vehicle)) τις κληρονομούν και προσθέτουν δικές τους (super για τον κατασκευαστή)· ή Ζώο → Ψάρι/Έντομο/Θηλαστικό, Person → Student/Teacher.

Κριτήρια αξιολόγησης:

  • Ιεραρχία με υπερκλάση/υποκλάσεις + κώδικας ή σαφής περιγραφή του τι κληρονομείται.

Ερώτηση 7 — Ενθυλάκωση και τα πλεονεκτήματά της

Ερώτηση: Τι είναι η ενθυλάκωση και ποια τα βασικά της πλεονεκτήματα.

Απάντηση:

  • Ενθυλάκωση (encapsulation): η ιδιότητα που προσφέρουν οι κλάσεις να «κρύβουν» τα ιδιωτικά δεδομένα τους από το υπόλοιπο πρόγραμμα και να εξασφαλίζουν ότι μόνο μέσω των δημόσιων μεθόδων τους μπορούν αυτά να προσπελαστούν (σελ. 213). Δύο χαρακτηριστικά: ① συνδυάζει δεδομένα και μεθόδους σε έναν θύλακα (capsule) — η κλάση ως τύπος δεδομένων περιλαμβάνει μεταβλητές/πεδία (ιδιότητες), κατασκευαστές και μεθόδους λειτουργιών· ② ελέγχει την πρόσβαση στα δεδομένα (information hiding) — η κλάση εμφανίζει μια διεπαφή (interface) με τις λειτουργίες της και κρύβει τις λεπτομέρειες υλοποίησης, οπότε χρησιμοποιούμε τα αντικείμενα χωρίς να ξέρουμε πώς υλοποιήθηκαν (ο οδηγός οδηγεί χωρίς να ξέρει τη μηχανή· ο τελεστής in χωρίς να ξέρουμε τον αλγόριθμο αναζήτησης). Επιτυγχάνεται με τους τροποποιητές πρόσβασης public/private/protected και τις μεθόδους get()/set()· στην Python με σύμβαση (διπλή κάτω παύλα).
  • Πλεονεκτήματα (σελ. 215):Επιτρέπει έλεγχο: η χρήση του αντικειμένου γίνεται μόνο μέσα από τις μεθόδους του — δεν επιτρέπεται η άμεση αλλαγή των δεδομένων του από άλλα αντικείμενα (προστασία από λάθη/ασυνέπειες). ② Επιτρέπει αλλαγές: η χρήση του αντικειμένου δεν αλλάζει αν αλλάξουν τα δεδομένα ή η εσωτερική υλοποίηση, αρκεί να παραμείνουν τα ίδια πρότυπα μεθόδων (η διεπαφή) — ο οδηγός οδηγεί το ίδιο βενζινοκίνητο, πετρελαιοκίνητο ή αεριοκίνητο αυτοκίνητο.

Σύνοψη: (ενδεικτική) Ενθυλάκωση = δεδομένα + μέθοδοι σε έναν θύλακα και απόκρυψη των ιδιωτικών δεδομένων, προσπελάσιμων μόνο μέσω δημόσιων μεθόδων (διεπαφή vs υλοποίηση, public/private/protected, get/set)· πλεονεκτήματα: έλεγχος (όχι άμεση αλλαγή δεδομένων) και ευκολία αλλαγών (η υλοποίηση αλλάζει, η χρήση όχι).

Κριτήρια αξιολόγησης:

  • Ορισμός με τα δύο χαρακτηριστικά + τα δύο πλεονεκτήματα.

Ερώτηση 8 — Τι είναι ένα γεγονός, με παραδείγματα

Ερώτηση: Τι είναι ένα γεγονός; Δώστε παραδείγματα.

Απάντηση:

  • Γεγονός (event): ένα συμβάν, εξωτερικό του αντικειμένου, που καθορίζει τη συμπεριφορά του — μαζί με έναν χειριστή γεγονότος (event handler), δηλαδή ένα κομμάτι κώδικα (στην Python μια συνάρτηση/μέθοδο) που υλοποιεί την ανταπόκριση του αντικειμένου στο γεγονός (σελ. 217). Ένα γεγονός προκαλεί ένα μήνυμα — σύνολο συναφών δεδομένων που σκοπό έχει να προκαλέσει κάποια προγραμματισμένη αντίδραση· ένα μήνυμα μεταξύ εφαρμογών ή αντικειμένων μπορεί να είναι το ίδιο γεγονός. Για να ενδιαφέρει την εφαρμογή, πρέπει να υπάρχει προγραμματισμένη ανταπόκριση σε αυτό.
  • Γεννήτριες γεγονότων: το ίδιο το σύστημα και τα μέρη του (ιδίως οι μονάδες εισόδου/εξόδου), άλλες εφαρμογές που επικοινωνούν με τη δική μας, άλλα αντικείμενα της εφαρμογής μας.
  • Παραδείγματα: το κλικ στο αριστερό κουμπί του ποντικιού ('<Button-1>' στην Tkinter), το πάτημα του πλήκτρου Return/ENTER ('<Return>'), το πάτημα του πλήκτρου «G»· το πάτημα ενός κουμπιού σε γραφική διεπαφή (Quit, «Πάτα για να παίξεις!» — χειριστής η συνάρτηση του command), η επιλογή ενός Radiobutton, η κίνηση/απελευθέρωση του ποντικιού, η αλλαγή μεγέθους παραθύρου, το κλείσιμο παραθύρου· εκτός GUI: η άφιξη αίτησης σε διακομιστή ιστού (μοντέλο πελάτη/εξυπηρετητή), η λήψη μηνύματος από άλλη εφαρμογή, ένα χρονόμετρο που λήγει. Τα γεγονότα δρομολογούνται στους χειριστές είτε χωρίς κεντρικό έλεγχο, είτε μέσω διανεμητή, είτε με το μοντέλο του παρατηρητή (εγγραφή χειριστών — bind στην Tkinter).

Σύνοψη: (ενδεικτική) Γεγονός = εξωτερικό συμβάν που καθορίζει τη συμπεριφορά ενός αντικειμένου μέσω ενός χειριστή (συνάρτηση που υλοποιεί την ανταπόκριση)· προκαλεί μήνυμα· πηγές: σύστημα/Ε-Ε, άλλες εφαρμογές, άλλα αντικείμενα. Παραδείγματα: αριστερό κλικ, πάτημα Return ή G, πάτημα κουμπιού GUI, επιλογή Radiobutton, αίτηση σε web server, λήψη μηνύματος.

Κριτήρια αξιολόγησης:

  • Ορισμός (γεγονός + χειριστής + μήνυμα) + τουλάχιστον τρία παραδείγματα.

 ΣΧΟΛΙΚΟ ΒΙΒΛΙΟ