1. Panagiotis Mavrogiorgos
  2. Python Tutorial (Greek)

Commits

Panagiotis Mavrogiorgos  committed ce4334d

Expanded composition.

  • Participants
  • Parent commits 5e7d43f
  • Branches default

Comments (0)

Files changed (1)

File source/object_oriented_programming.rst

View file
 Αντικειμενοστραφής Προγραμματισμός (Object-Oriented Programming)
 ****************************************************************
 
+Προγραμματιστικά παραδείγματα
+=============================
+
 .. Note::
 
     H ενότητα αυτή είναι περισσότερο πληροφοριακή. Το "ζουμί" ξεκινάει από την
     επόμενη.
 
-O Αντικειμενοστραφής Προγραμματισμός, όπως λέει και το όνομα συνδέεται άμεσα με
-τις αντικείμενα και κατά συνέπεια, όπως θα δούμε και στη συνέχεια, και με τις
-κλάσεις.  Τι είναι όμως ο Αντικειμενικοστραφής Προγραμματισμός;
+O Αντικειμενοστραφής Προγραμματισμός (Object-Oriented Programming ή OOP για
+συντομία), όπως λέει και το όνομά του συνδέεται άμεσα με τα αντικείμενα και κατά
+συνέπεια, όπως θα δούμε και στη συνέχεια, και με τις κλάσεις.  Τι είναι όμως
+ο Αντικειμενοστραφής Προγραμματισμός;
 
-Κατ' ουσίαν, ο Αντικειμενικοστραφής Προγραμματισμός είναι ένας τρόπος οργάνωσης
-των προγραμμάτων που γράφουμε.  Ο τρόπος αυτός οργάνωσης, δεν είναι φυσικά ούτε
-μοναδικός ούτε καν ο βέλτιστος.  Άλλοι τρόποι οργάνωσης είναι ο *διαδικαστικός*
-(procedural ή imperative) και ο *συναρτησιακός* (functional).  Συνηθίζεται,
-αυτοί οι τρόποι οργάνωσης ή τεχνικές οργάνωσης των προγραμμάτων να ονομάζονται
-προγραμματιστικά παραδείγματα (programming paradigms).
+Κατ' ουσίαν, ο OOP είναι ένας τρόπος οργάνωσης των προγραμμάτων που γράφουμε.
+Ο τρόπος αυτός οργάνωσης, δεν είναι φυσικά ούτε μοναδικός, ούτε καν ο βέλτιστος.
+Άλλοι τρόποι οργάνωσης είναι ο *διαδικαστικός* (procedural ή imperative) και
+ο *συναρτησιακός* (functional).  Συνηθίζεται, αυτοί οι τρόποι οργάνωσης
+ή τεχνικές οργάνωσης των προγραμμάτων να ονομάζονται προγραμματιστικά
+παραδείγματα (programming paradigms).
 
 Η επιλογή του προγραμματιστικού παραδείγματος το οποίο θα χρησιμοποιήσουμε
 εξαρτάται από το πρόβλημα το οποίο καλούμαστε να επιλύσουμε, αλλά και από τη
 γλώσσα προγραμματισμού την οποία χρησιμοποιούμε.  Δεν επιτρέπουν όλες οι γλώσσες
 προγραμματισμού τη χρήση όλων των προγραμματιστικών παραδειγμάτων.  Π.χ.
 υπάρχουν γλώσσες που επιτρέπουν τη δημιουργία μόνο διαδικαστικών προγραμμάτων
-όπως η C και η Fortran.  Υπάρχουν άλλες που επιτρέπουν τη δημιουργία μόνο
+όπως η Fortran.  Υπάρχουν άλλες που επιτρέπουν τη δημιουργία μόνο (ή κυρίως)
 συναρτησιακών προγραμμάτων, όπως η Lisp και οι πολλές παραλλαγές της.  Ενώ
 υπάρχουν και γλώσσες που επιτρέπουν, με περισσότερη η λιγότερη ευκολία, να
 εφαρμόσεις περισσότερα από ένα προγραμματιστικά παραδείγματα.  Η Python ανήκει
-σε αυτήν την κατηγορία καθώς είναι δυνατό να αναπτυχθεί κώδικας που χρησιμοποιεί
+σε αυτήν την κατηγορία καθώς σου επιτρέπει να γράψεις κώδικα που χρησιμοποιεί
 και τα τρία προγραμματιστικά παραδείγματα.
 
 Όπως έχει αποδειχτεί στην πράξη, η πλειοψηφία των προβλημάτων που καλείται να
 λύσει ένας προγραμματιστής μπορούν να λυθούν με οποιοδήποτε από τα
-προγραμματιστικά παραδείγματα.  Απλά συχνά κάποιο από τα προγραμματιστικά
-παραδείγματα προσφέρεται περισσότερο για την επίλυση ενός συγκεκριμένου
-προβλήματος.
+προγραμματιστικά παραδείγματα. Η επιλογή του ενός ή του άλλου είναι συχνά θέμα
+συνήθειας (τι έχουμε μάθει να χρησιμοποιούμε). Αυτό που έχει τη μεγαλύτερη
+σημασία είναι να σχεδιάσεις σωστά το πρόγραμμα σου. Απλά συχνά κάποιο από τα
+προγραμματιστικά παραδείγματα προσφέρεται περισσότερο για την επίλυση ενός
+συγκεκριμένου προβλήματος.
 
 .. Note::
 
 πιθανά έρχονται στο μυαλό.  Αν προσπαθήσουμε να δούμε το κοινό σημείο όλων των
 παραπάνω θα δούμε ότι πρόκειται για:
 
-    "Οντότητες" (έμψυχες ή άψυχες) οι οποίες έχουν συγκεκριμένες
+    *Οντότητες* (έμψυχες ή άψυχες) οι οποίες έχουν συγκεκριμένες
     **ιδιότητες** ή/και μπορούν να **εκτελούν συγκεκριμένες ενέργειες**.
 
 Ας δούμε μερικά παραδείγματα:
 
 Ο παραπάνω "ορισμός" των αντικειμένων είναι φυσικά πολύ γενικός και δύσκολα θα
 άντεχε σε ενδελεχή εξέταση από έναν φιλόλογο.  Παρόλα αυτά, είναι ένας ορισμός
-που μας βολεύει ιδιαίτερα όταν επιστρέφουμε στον κόσμο της Python και αυτό
-γιατί, τα αντικείμενα (objects) της Python είναι εκείνες οι "οντότητες" οι
-οποίες μας επιτρέπουν να περιγράφουμε κάθε τι που έχει ιδιότητες και μπορεί να
-εκτελεί ενέργειες.  Με λίγα λόγια δηλαδή, μέσω των αντικειμένων μπορούμε να
-περιγράψουμε πρακτικά σχεδόν οτιδήποτε συναντάμε στον υλικό κόσμο.
+που μας βολεύει ιδιαίτερα όταν επιστρέφουμε στον κόσμο του Αντικειμενοστραφούς
+Προγραμματισμού και αυτό γιατί τα αντικείμενα (objects) είναι εκείνες οι
+"οντότητες" οι οποίες μας επιτρέπουν να περιγράφουμε κάθε τι που έχει ιδιότητες
+και μπορεί να εκτελεί ενέργειες.  Με λίγα λόγια δηλαδή, μέσω των αντικειμένων
+μπορούμε να περιγράψουμε πρακτικά σχεδόν οτιδήποτε συναντάμε στον υλικό κόσμο.
 
 Χρησιμοποιώντας την ορολογία της Python, οι ιδιότητες ενός αντικειμένου
 ονομάζονται **attributes**, ενώ οι ενέργειές που μπορεί να εκτελέσει ονομάζονται
 .. Warning::
 
     Η σύνταξη των κλάσεων στην Python είναι αρκετά απλή.  Παρόλα αυτά, σε πρώτη
-    φάση θα χρησιμοποιήσουμε μια ακόμη πιο απλοποιημένη σύνταξη προκειμένου να
-    καταλάβουμε ευκολότερα ορισμένες βασικές έννοιες του Αντικειμενικοστραφούς
-    Προγραμματισμού.
+    φάση θα χρησιμοποιήσουμε μια ακόμη πιο απλοποιημένη σύνταξη (η οποία όμως
+    μοιάζει αρκετά με Python) προκειμένου να καταλάβουμε ευκολότερα ορισμένες
+    βασικές έννοιες του Αντικειμενοστραφούς Προγραμματισμού.
 
     Την κανονική σύνταξη της Python θα την δούμε στη συνέχεια.
 
-Μια κλάση δεν είναι τίποτα άλλο παρά ένας ορισμός. Αυτό που ορίζει είναι το
+Μια κλάση δεν είναι τίποτα άλλο παρά ένας **ορισμός**. Αυτό που ορίζει είναι το
 ποιες ιδιότητες (attributes) και ποιες μεθόδους (methods) θα έχει ένα
 αντικείμενο.
 
     κλάσεις μας θα είναι αρκετά πιο σύνθετες.
 
 Τώρα θα χρησιμοποιήσουμε την κλάση που ορίσαμε παραπάνω για να δημιουργήσουμε
-δύο νέες γάτες (δηλαδή δύο νέα *αντικείμενα Γάτας*).  Τη γατα του Joe, μια
+δύο νέες γάτες (δηλαδή δύο νέα *αντικείμενα Γάτας*).  Τη γάτα του Joe, μια
 θηλυκή γάτα δύο ετών που τη λένε "Kitty" και τη γάτα της Mary, μια αρσενική γάτα
 οκτώ ετών που τη λένε "Paul"::
 
 νέων αντικειμένων που θα δημιουργήσουμε από μία κλάση.  Μπορούμε να
 δημιουργήσουμε όσα νέα αντικείμενα θέλουμε.
 
+Όλα τα νέα αντικείμενα θα έχουν ακριβώς τις ίδιες ιδιότητες (attributes) και τις
+ίδιες μεθόδους.  Οι τιμές των ιδιοτήτων τους όμως θα είναι διαφορετικές μεταξύ
+τους. Μπορούμε φυσικά να δώσουμε ακριβώς τις ίδιες τιμές στις ιδιότητες, οπότε θα
+δημιουργηθούν δύο όμοια αντικείμενα, αλλά συνήθως δεν έχουμε λόγο να κάνουμε
+κάτι τέτοιο.
+
 .. Note::
 
     Υπενθυμίζουμε ότι προηγουμένως ορίσαμε τις κλάσεις σαν *εργοστάσιο
     κατασκευάσουν αντικείμενα με διαφορετικές ιδιότητες σε όποια ποσότητα
     επιθυμούμε.
 
-Όλα τα νέα αντικείμενα θα έχουν ακριβώς τις ίδιες ιδιότητες (attributes) και τις
-ίδιες μεθόδους.  Οι τιμές των ιδιοτήτων τους όμως θα είναι διαφορετικές μεταξύ
-τους. Μπορούμε φυσικά να δώσουμε ακριβώς τις ίδιες τιμές στις ιδιότητες, οπότε θα
-δημιουργηθούν δύο όμοια αντικείμενα, αλλά συνήθως δεν έχουμε λόγο να κάνουμε
-κάτι τέτοιο.
-
-Στην ορολογία του Αντικειμενικοστραφούς Προγραμματισμού, όλα τα νέα αντικείμενα
+Στην ορολογία του Αντικειμενοστραφούς Προγραμματισμού, όλα τα νέα αντικείμενα
 που δημιουργούνται από μία κλάση ονομάζονται *στιγμιότυπα* (instances).
 
 .. Note::
 
     Το ότι οι μέθοδοι είναι ακριβώς ίδιες με τις συναρτήσεις δεν είναι απόλυτα
     ακριβές. Στην ψευδογλώσσα που χρησιμοποιούμε, ισχύει μεν κάτι τέτοιο αλλά
-    στην Python οι μέθοδοι έχουν μία διαφορά από τις συναρτήσεις.  Κρατήστε το
-    στο μυαλό σας, αν και για την ώρα δεν είναι σημαντικό.
+    στην Python οι μέθοδοι έχουν μία διαφορά από τις συναρτήσεις. Για την ώρα
+    δεν είναι σημαντικό. Απλά κρατήστε το στο μυαλό σας.
 
 Κληρονομικότητα (Inheritance)
 =============================
 Με τον όρο κληρονομικότητα, εννοούμε τη δυνατότητα που έχει μια κλάση να
 *κληρονομεί* όλες τις ιδιότητες και τις μεθόδους μιας άλλης κλάσης.
 Χρησιμοποιώντας λίγο πιο επίσημη ορολογία, λέμε ότι η κλάση που ορίζεται πρώτη
-είναι η *βασική κλάση* (base class) και η κλάση που κληρονομεί τη βάσική κλάση
+είναι η *βασική κλάση* (base class) και η κλάση που κληρονομεί τη βασική κλάση
 ονομάζεται *παράγωγη κλάση* (derived class). Εναλλακτικά οι βασικές κλάσεις
 ονομάζονται και *υπερκλάσεις* ενώ οι παράγωγες κλάσεις ονομάζονται *υποκλάσεις*.
 
 
 .. Warning::
 
-    Η πολλαπλή κληρονομικότητα είναι περίπλοκη. H χρήση της πολλαπλής
-    κληρονομικότητας είναι συνήθως ένδειξη κακού design.  Στην πλειοψηφία των
-    περιπτώσεων, υπάρχει απλούστερος τρόπος να κάνουμε αυτό που θέλουμε από το
-    να καταφύγουμε στην πολλαπλή κληρονομικότητα. Καλό είναι να την αποφεύγετε
-    (εκτός και αν ξέρετε τι κάνετε, οπότε μάλλον δε θα διαβάζετε αυτό το κείμενο
-    :P).
+    Η πολλαπλή κληρονομικότητα είναι περίπλοκη. Το παράδειγμά μας δεν
+    αναδεικνύει τη δυσκολία της, αλλά πιστέψτε με, δεν είναι εύκολο να την
+    κάνεις να συμπεριφερθεί σωστά. H χρήση της πολλαπλής κληρονομικότητας είναι
+    συνήθως ένδειξη κακού design. Αυτός είναι και ο λόγος που υπάρχουν πολλές
+    γλώσσες προγραμματισμού που υποστηρίζουν μόνο απλή κληρονομικότητα (πχ
+    Java). Στην πλειοψηφία των περιπτώσεων, υπάρχει απλούστερος τρόπος να
+    κάνουμε αυτό που θέλουμε από το να καταφύγουμε στην πολλαπλή
+    κληρονομικότητα. Καλό είναι να την αποφεύγετε (εκτός και αν ξέρετε τι
+    κάνετε, οπότε μάλλον δε θα διαβάζετε αυτό το κείμενο :P).
 
 Στο σημείο αυτό, οφείλουμε να διασαφηνίσουμε ότι μία αλληλουχία κλάσεων που
 διαδοχικά κληρονομούν η μία την άλλη **δεν** είναι πολλαπλή κληρονομικότητα.
-Παραδείγματος χάρη το ακόλουθο παράδειγμα είναι απολύτα τυπική απλή
+Παραδείγματος χάρη το ακόλουθο παράδειγμα είναι απόλυτα τυπική απλή
 κληρονομικότητα::
 
     class Animal():
 γενεαλογικά δέντρα του ζωικού και του φυτικού βασιλείου αποτελούν πολύ
 χαρακτηριστικά παραδείγματα τέτοιου είδους αλληλουχιών.
 
-Πολλαπλή Κληρονομικότητα (Multiple Inheritance)
------------------------------------------------
+Πότε χρησιμοποιούμε την Κληρονομικότητα;
+----------------------------------------
 
 Απλά για λόγους πληρότητας πρέπει να αναφέρουμε και την *πολλαπλή
 κληρονομικότητα* (multiple inheritance). Πολλαπλή κληρονομικότητα σημαίνει μία
 Σύνθεση (Composition)
 =====================
 
+Τι είναι η Σύνθεση;
+--------------------
+
+Η *Σύνθεση* (Composition) είναι η δεύτερη τεχνική του OOP που θα αναπτύξουμε.
+
+Όπως θα θυμάστε, είχαμε αναφέρει προηγουμένως ότι υπάρχει μια αντιστοιχία μεταξύ
+των "ιδιοτήτων" (attributes) μιας κλάσης και των "ουσιαστικών" της φυσικής
+γλώσσας. Εκτός από αυτό όμως, αναφέραμε ότι και τα ίδια τα αντικείμενα (objects)
+είναι "ουσιαστικά".
+
+Συνδυάζοντας τις δύο παραπάνω προτάσεις προκύπτει ότι:
+
+    **οι ιδιότητες (attributes) ενός αντικειμένου είναι και αυτές με τη σειρά
+    τους αντικείμενα!**
+
+Η παρατήρηση αυτή είναι η βασική ιδέα πίσω από την τεχνική της Σύνθεσης.
+
+Η Σύνθεση στην πράξη
+--------------------
+
+Ας δούμε ένα παράδειγμα. Ας σκεφτούμε μια μηχανή αυτοκινήτου. Η μηχανή αυτή
+αποτελείται από πολλά εξαρτήματα. Κύλινδροι, βαλβίδες, πιστόνια, μπουζί είναι
+μερικά μόνο από αυτά.  Η σχέση που συνδέει την μηχανή με τα εξαρτήματά της είναι
+η εξής:
+
+    Η *Μηχανή* **έχει** τους *κυλίνδρους*.
+
+    Η *Μηχανή* **έχει** τις *βαλβίδες*.
+
+    Η *Μηχανή* **έχει** τα *πιστόνια*.
+
+Δηλαδή, η *μηχανή* **έχει** *εξαρτήματα-ιδιότητες*, το καθένα από
+τα οποία είναι ένα ξεχωριστό αντικείμενο (object). Στην ορολογία του OOP αυτού του είδους
+η σχέση ονομάζεται "**has-a relationship**". Ας το δούμε και στην πράξη::
+
+    class Piston():
+        pass
+
+    class Valves():
+        pass
+
+    class Cylinders():
+        pass
+
+    class Engine():
+        pistons = Pistons()
+        valves = Valves()
+        cylinders = Cylinders()
+
+Όπως βλέπουμε οι *ιδιότητες* (attributes) της *Μηχανής* **είναι** *instances*
+μιας άλλης κλάσης. Στο παράδειγμα αυτό οι κλάσεις *Πιστονιού*, *Βαλβίδας* και
+*Κυλίνδρου* δεν έχουν δικές τους ιδιότητες/μεθόδους, αυτό όμως έχει γίνει καθαρά
+για λόγους απλότητας. Δεν υπάρχει κανένας τέτοιου τύπου περιορισμός.  Ας δούμε
+ένα ακόμα παράδειγμα::
+
+    class Tire():
+        size
+        max_pressure
+
+    class Engine():
+        cubic_capacity
+        engine_type
+
+    class Car():
+        model
+        color
+
+        tires = Tire(size=18, max_pressure=30)
+        engine = Engine(type="V8", cubic_capacity=1800)
+
+Λογικά πλέον δεν χρειάζονται πολλές εξηγήσεις. Ένα αυτοκίνητο *έχει* ελαστικά
+και μηχανή. Ορίζουμε αρχικά λοιπόν τις κλάσεις *Ελαστικό* και *Μηχανή* με τις
+κατάλληλες ιδιότητες και μεθόδους. Στη συνέχεια ορίζουμε την κλάση *Αυτοκίνητο*
+η οποία έχει ως ιδιότητες (attributes) *αντικείμενα Ελαστικού* και *αντικείμενα
+μηχανής*. Πέρα από αυτές τις δύο ιδιότητες, η κλάση μπορεί να έχει και άλλες
+ιδιότητες όπως *μοντέλο* και *χρώμα*.
+
+Ας φτιάξουμε τώρα μερικά *αντικείμενα Αυτοκινήτου*::
+
+    my_car = Car(model="Ford Escort", color="Blue")
+    your_car = Car(model="Ferrari Testarossa", color="Red")
+
+.. Warning::
+
+    Στο παράδειγμα αυτό, οι instances των ελαστικών και της μηχανής
+    δημιουργούνται μέσα στο σώμα της κλάσης *Αυτοκίνητο*. Ως αποτέλεσμα αυτού
+    όλα τα *αντικείμενα Αυτοκινήτου* θα έχουν την ίδια μηχανή και τα ίδια ελαστικά.
+    Αν θέλουμε να φτιάξουμε αυτοκίνητα με διαφορετική μηχανή και ελαστικά πως θα
+    το πετύχουμε; Αυτό το ερώτημα θα το απαντήσουμε αργότερα, καθώς είναι
+    καλύτερα να το εξηγήσουμε χρησιμοποιώντας την κανονική σύνταξη της Python.
+    Για την ώρα λοιπόν, δώστε περισσότερη προσοχή στην *Ιδέα* της *Σύνθεσης* και
+    λιγότερο στην υλοποίηση
+
+
+
+
 Καλά όλα αυτά... Εμένα γιατί μου χρειάζονται;
 =============================================
 
-Κάπου εδώ βέβαια, εύλογα δημιουργείται το ερώτημα: "**Καλά όλα αυτά... Εμένα γιατί μου χρειάζονται;**"
-
 Η απάντηση σε αυτό το ερώτημα δεν είναι και τόσο απλή. Μια σύντομη αναζήτηση στο
-ιντερνετ σχετικά με τα πλεονεκτήματα του Αντικειμενικοστραφούς Προγραμματισμού
+internet σχετικά με τα πλεονεκτήματα του Αντικειμενοστραφούς Προγραμματισμού
 (benefits/advantages of Object-Oriented Programming) θα επιστρέψει πλήθος
 σελίδων που απαντούν στο ερώτημα αυτό. Οι απαντήσεις χωρίζονται σε δύο σκέλη:
 
 κληρονομικότητα αποφεύγουμε να επαναλάβουμε κώδικα (αρχή "Do not Repeat
 Yourself" - DRY). Αυτό γίνεται γιατί όλα τα αντικείμενα μας μοιράζονται τον ίδιο
 κώδικα. Οι κοινές μέθοδοι ορίζονται μία φορά στην υπερκλάση και όλες οι
-υποκλάσεις απλά την κληρονομούνε. Με τον τρόπο αυτό μειώνεται το μέγεθος του
+υποκλάσεις απλά την κληρονομούν. Με τον τρόπο αυτό μειώνεται το μέγεθος του
 κώδικα. Λιγότερος κώδικας σημαίνει λιγότερα bugs, πιο κατανοητός κώδικας και πιο
 κώδικας που είναι πιο εύκολο να συντηρηθεί.
 
 **αφαίρεσης** (abstraction) μειώνοντας με αυτόν τον τρόπο την πολυπλοκότητα των
 προβλημάτων που καλούμαστε να λύσουμε (και όποιος κατάλαβε, κατάλαβε :P).
 
-Ενταξει, επειδή η προηγούμενη παράγραφος είναι σκόπιμα δυσνόητη και γενικόλογη,
+Εντάξει, επειδή η προηγούμενη παράγραφος είναι σκόπιμα δυσνόητη και γενικόλογη,
 ας προσπαθήσουμε να κάνουμε τα πράγματα λίγο πιο λιανά.