oop:introduction

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== Εισαγωγή στον Αντικειμενοστραφή Προγραμματισμό ====== Κεντρικό στοιχείο του Αντικειμενοστραφούς Προγραμματισμού είναι η χρήση αντικειμένων. Τα αντικείμενα στον αντικειμενοστραφή προγραμματισμό τείνουν να προσομοιάσουν ευρύτερες έννοιες που υφίστανται στον πραγματικό κόσμο. Παραδείγματα αντικειμένων μπορεί να είναι τα ακόλουθα: * το αυτοκίνητο * το ποδήλατο * το τρένο Τα "αντικείμενα" στον πραγματικό κόσμο έχουν δύο βασικά χαρακτηριστικά: - **Κατάσταση (state):** Κάθε αντικείμενο διέπεται από συγκεκριμένα χαρακτηριστικά που ορίζουν την κατάσταση του. Για παράδειγμα ένα αυτοκίνητο έχει συγκεκριμένο χρώμα, ανήκει σε συγκεκριμένο μοντέλο και κάθε χρονική στιγμή έχει μία ταχύτητα και μία κατεύθυνση κίνησης. Τα παραπάνω χαρακτηριστικά διέπουν όλα τα αυτοκίνητα, αλλά κάθε αυτοκίνητο έχει τις δικές του τιμές οι οποίες μπορεί να διαφέρουν από τις τιμές άλλων αυτοκινήτων. - **Συμπεριφορά (behaviour)**: Κάθε αντικείμενο διέπεται από συγκεκριμένους κανόνες συμπεριφοράς. Για παράδειγμα σε ένα αυτοκίνητο εάν στρίψουμε το τιμόνι στα αριστερά το αυτοκίνητο κινείται αριστερά. __Ο παραπάνω γενικός κανόνας ισχύει για όλα τα αυτοκίνητα__. Η σχέση μεταξύ της γωνίας στροφής του τιμονιού του αυτοκινήτου και της αλλαγή πορείας που αυτή συνεπάγεται μπορεί να διαφέρει μεταξύ διαφορετικών μοντέλων. Σε αναλογία των παραπάνω, τα αντικείμενα στον αντικειμενοστραφή προγραμματισμό διαθέτουν: * **Δεδομένα //(μεταβλητές)//:** Τα δεδομένα περιγράφουν την κατάσταση του κάθε αντικειμένου και μπορεί η τιμή τους να διαφέρει από αντικείμενο σε αντικείμενο. * **Μεθόδους //(συναρτήσεις)//:** Οι μέθοδοι περιγράφουν την συμπεριφορά του αντικειμένου και είναι κοινές για όλα τα αντικείμενα ενός συγκεκριμένου τύπου. Για παράδειγμα όλα τα αυτοκίνητα ενός συγκεκριμένου μοντέλου διέπονται από την ίδια σχέση μεταξύ της γωνίας στροφής του τιμονιού και της γωνίας στροφής των δύο μπροστινών τροχών. ===== Η Κλάση ===== Τα αντικείμενα που περιγράψαμε παραπάνω αποτελούν (εναλλακτικές) υλοποιήσεις ενός βασικού σχεδίου. Για παράδειγμα, όταν παράγεται ένα αυτοκίνητο, αυτό αποτελεί υλοποίηση του βασικού σχεδίου του αυτοκινήτου, έτσι όπως αυτό υλοποιείται από το εργαστάσιο κατασκευής. Μέρος του **σχεδίου** είναι η ύπαρξη κάποιων παραμέτρων όπως το χρώμα ή το επίπεδο του εξοπλισμού. | Τον ρόλο του **σχεδίου** με την έννοια που αναφέρεται παραπάνω τον παίζει η **κλάση**. Η κλάση αποτελεί το σχέδιο με βάση το οποίο αντικείμενα του συγκεκριμένου τύπου της κλάσης υλοποιούνται σε ένα πρόγραμμα. Τα αντικείμενα μιας κλάσης διέπονται από τις ίδιες //εσωτερικές μεταβλητές// (δεδομένα) και από τις ίδιες //συμπεριφορές// (συναρτήσεις). Τα αντικείμενα της ίδιας κλάσης μπορεί να διαφέρουν ως προς το περιεχόμενο των //εσωτερικών τους μεταβλητών//. | {{ :oop:class-object.png ?200|}} | | Το διπλανό σχήμα απεικονίζει διαφορετικές υλοποιήσεις ενός αυτοκινήτου με βάση το αρχικό σχέδιο του συγκεκριμένου μοντέλου. Αντιστρέφοντας το παράδειγμα του αυτοκινήτου, όλα τα αυτοκίνητα του συγκεκριμένου μοντέλου αποτελούν υλοποιήσεις του ίδιου αρχικού σχεδίου. | {{:oop:astra-class-object.png?250 }} | ==== Κατασκευαστές της Κλάσης (Class Constructors) ==== Στον πραγματικό κόσμο μπορούμε να έχουμε διαφορετικές υλοποιήσεις ενός σχεδίου, διαφοροποιώντας κάποιες αρχικές παραμέτρους στο σχέδιο αυτό. Για παράδειγμα, μπορούμε να έχουμε διαφορετικές εκδόσεις για τα αυτοκίνητα ενός μοντέλου (π.χ. διαφοροποίηση στο επίπεδο του εξοπλισμού ή στο χρώμα). Ανάλογα, στον αντικειμενοστραφή προγραμματισμό, μία κλάση μπορεί να δώσει διαφοροποιημένα αντικείμενα. Κάθε αντικείμενο υλοποιείται από μία μέθοδο που καλείται κατασκευαστής (//constructor//). Ο κατασκευαστής της κλάσης υλοποιεί το κάθε αντικείμενο με βάση το σχέδιο της κλάσης μπορεί να κληθεί για διαφορετικά αντικείμενα με διαφορετικές παραμέτρους, οδηγώντας τελικά σε διαφοροποιημένα αντικείμενα ως προς τα χαρακτηριστικά τους. Mία κλάση μπορεί να έχει **περισσότερους του ενός** κατασκευαστές. Οι κατασκευαστές είναι συναρτήσεις (μέθοδοι) που κάνουν τα εξής: * Δεσμεύουν την απαραίτητη μνήμη για το νέο αντικείμενο. * Αρχικοποιούν το αντικείμενο με βάση τις αρχικές τιμές των παραμέτρων με τις οποίες καλείται ο κατασκευαστής. ==== Περιεχόμενα της Κλάσης ==== Κάθε κλάση περιέχει κατά βάση τρία (3) πράγματα: - **Δεδομένα**. Τα δεδομένα διακρίνονται σε: * Βασικούς τύπους δεδομένων (Primitive Types), char, int, long, float, double, arrays κλπ * Σύνθετους τύπους δεδομένων (Reference Types), Strings, Arrays, Objects κλπ - **Kατασκευαστές αντικειμένων**. - **Μεθόδους** (το αντίστοιχο των συναρτήσεων στην γλώσσα C) ==== Κληρονομικότητα ==== Στον πραγματικό κόσμο πολλά πράγματα μοιράζονται κοινά χαρακτηριστικά. Για παράδειγμα: * Υπάρχουν επιμέρους τύποι ποδηλάτων, όπως mountain, street, bmx κλπ * Υπάρχουν επιμέρους τύποι αυτοκινήτων, sport, 4x4, sedan, coupe, supercars, luxury cars. Με βάση την παραπάνω παρατήρηση, μπορούμε να ορίσουμε κλάσεις που περιγράφουν γενικότερες έννοιες και στην συνέχεια να τις εξειδικεύσουμε δημιουργώντας νέες κλάσεις που περιγράφουν πιο ειδικές έννοιες. Ο λόγος που θα θέλαμε να κάνουμε κάτι τέτοιο είναι ότι κατά την εξέλιξη του λογισμικού θέλουμε κατά το δυνατόν να επαναχρησιμοποιήσουμε κώδικα που ήδη έχουμε, δημιουργώντας πιο σύνθετα και εξελιγμένα μοντέλα του υφιστάμενου λογισμικού. Όταν εφευρέθηκε το ποδήλατο με ταχύτητες, ο εφευρέτης χρησιμοποίησε το υφιστάμενο βασικό σχέδιο του ποδηλάτου για να προσθέσει τον μηχανισμό των ταχυτήτων και να δημιουργήσει ένα νέο τύπο ποδηλάτου, το ποδήλατο με ταχύτητες. Σε αναλογία με τον πραγματικό κόσμο, ας υποθέσουμε ότι έχουμε μία κλάση που περιγράφει το κλασσικό ποδήλατο χωρίς ταχύτητες μέσω των παρακάτω τεσσάρων μεταβλητών. - ταχύτητα κίνησης - θέση - κατεύθυνση κίνησης - ταχύτητα περιστροφής των πεταλιών Παράλληλα, η κλάση μας θα πρέπει να έχει και κάποιες συναρτήσεις για την μεταβολή της τιμής των παραπάνω μεταβλητών στις οποίες δεν θα επεκταθούμε σε αυτό το σημείο. Ας υποθέσουμε τώρα ότι θέλουμε να σχεδιάσουμε το ποδήλατο με ταχύτητες. Θα χρειαστεί να προσθέσουμε μία νέα μεταβλητή που αντιπροσωπεύει την θέση της αλυσίδας στο γρανάζι μέσω ενός ακεραίου (π.χ. 1-5 για ένα ποδήλατο με 5 ταχύτητες). Η ιδιότητα της κληρονομικότητας μας επιτρέπει να δημιουργήσουμε τη νέα κλάση του ποδηλάτου με ταχύτητες, επεκτείνοντας την κλάση του κλασσικού ποδηλάτου και προσθέτοντας την επιπλέον μεταβλητή για την θέση της αλυσίδας στο γρανάζι και ανάλογη λειτουργικότητα μέσω συναρτήσεων. Η κληρονομικότητα μας επιτρέπει να μην γράψουμε την νέα κλάση από την αρχή αλλά να πατήσουμε πάνω σε ένα υφιστάμενο σχέδιο. Επεκτείνοντας την παραπάνω συλλογιστική μπορούμε να έχουμε πολλαπλές ιεραρχίες κλάσεων. Για παράδειγμα, από το ποδήλατο με ταχύτητες μπορεί να οριστεί το ποδήλατο για δύο επιβάτες με ταχύτητες ή το ποδήλατο για δύο επιβάτες με ταχύτητες και αμορτισέρ. //**ποδήλατο** --> **ποδήλατο με ταχύτητες** --> **ποδήλατο με ταχύτητες για δύο επιβάτες** -> **ποδήλατο με ταχύτητες και αμορτισέρ για δύο επιβάτες**//. Για το **ποδήλατο με ταχύτητες** η κλάση **ποδήλατο** αποτελεί την γονική κλάση (__Super Classes__). Αντίστοιχα για το **ποδήλατο**, το **ποδήλατο με ταχύτητες** αποτελεί υποκλάση (__Sub Class__) αυτού. | Στο διπλανή εικόνα παρουσιάζεται εποπτικά ένα παράδειγμα κληρονομικότητας της κλάσης του ποδηλάτου. Από την γενική κλάση του ποδηλάτου προκύπτουν δύο επιμέρους κλάσεις **α)** το ποδήλατο για δύο επιβάτες (χωρίς ταχύτητες) **β)** το ποδήλατο με ταχύτητες. <WRAP todo>Μπορείτε να προτείνετε κάποια άλλη ιεραρχία κλάσεων για κάποια άλλη οντότητα (π.χ. το αυτοκίνητο) σε αναλογία με αυτή που περιγράψαμε για το ποδήλατο;</WRAP>| {{:oop:bicycle-hierarchy.png?300 |}} | ==== Διεπαφές - Interfaces ==== Τα αντικείμενα στον πραγματικό κόσμο ορίζουν την διεπαφή τους με τον έξω κόσμο μέσα από συγκεκριμένα εργαλεία που καταλήγουν σε συγκεκριμένες πράξεις. Για παράδειγμα, * τα κουμπιά και η οθόνη του κινητού τηλεφώνου ή της τηλεόρασης ορίζουν τις δυνατότητες αλληλεπίδρασης με την συσκευή. * Το πληκτρολόγιο, το ποντίκι και η οθόνη ορίζουν τις δυνατότητες αλληλεπίδρασης με έναν επιτραπέζιο υπολογιστή. * Η σέλα, το τιμόνι, τα πετάλια και τα φρένα ορίζουν τις δυνατότητες αλληλεπίδρασης με ένα ποδήλατο. Ανάλογη είναι η λειτουργία της **διεπαφής** για τον αντικειμενοστραφή προγραμματισμό. Ορίζουμε μία **διεπαφή**, ως ένα σύνολο από μεθόδους (δηλ τρόπους αλληλεπίδρασης με τα αντικείμενα), δίνοντας μόνο τους ορισμούς των μεθόδων, χωρίς την υλοποίηση τους. Εάν μία κλάση υλοποιεί ΟΛΕΣ τις μεθόδους μιας διεπαφής, τότε η κλάση είναι σύμφωνη με την συγκεκριμένη διεπαφή. Ο τρόπος που υλοποιεί κάθε κλάση τις μεθόδους της διεπαφής είναι εσωτερικό θέμα της κλάσης και δεν ελέγχεται από την διεπαφή. Επιπλέον, μία κλάση μπορεί να υλοποιεί μία ή περισσότερες διεπαφές. Ας υποθέσουμε ότι ορίζεται η διεπαφή ''MotorPropelled'' η οποία περιγράφει ένα σύνολο μεθόδων που πρέπει να υλοποιούνται από μία κλάση προκειμένου τα αντικείμενα της κλάσης αυτής να είναι ''MotorPropelled'' (δηλαδή να κινούνται και με χρήση μηχανής εσωτερικής καύσης). Ας υποθέσουμε ότι οι μέθοδοι που χρειαζόμαστε είναι οι παρακάτω: * engineStart * engineStop * accelerate * getFuelConsumption * addFuel Αν οποιαδήποτε κλάση υλοποιεί τις παραπάνω μεθόδους τότε μπορούμε να πούμε ότι υλοποιεί το συγκεκριμένο interface, δηλ τα αντικείμενα της κλάσης αυτής είναι //MotorPropelled//. Η νέα κλάση μπορεί να είναι κάποια υποκλάση μιας ήδη γνωστής κλάσης (π.χ. μία υποκλάση της κλάσης //Bicycle//) αλλά μπορεί να είναι και οποιαδήποτε άλλη κλάση αυτοκινούμενου οχήματος ακόμη και μία κλάση που ορίζεται εξ' αρχής. Στον αντικειμενοστραφή προγραμματισμό, όσες κλάσεις υλοποιούν όλες τις παραπάνω μεθόδους, υλοποιούν συνολικά το interface. Ως εκ τούτου υποστηρίζουν τις ιδιότητες του interface αυτού. ==== Πλεονεκτήματα του Αντικ/στραφούς Προγραμματισμού ==== * **Αρθρωτή Δομή(Modularity):** O κώδικας μίας κλάσης μπορεί να σχεδιαστεί και να αναπτυχθεί εντελώς ανεξάρτητα από τον κώδικα άλλης κλάσης. Η υλοποίηση μίας κλάσης μπορεί να αλλάξει ριζικά χωρίς να επηρεαστεί ο κώδικας των κλάσεων που χρησιμοποιούν τη συγκεκριμένη κλάση. * **Απόκρυψη πληροφορίας:** Στον αντικειμενοστραφή προγραμματισμό δεν μας ενδιαφέρει η εσωτερική υλοποίηση κάθε κλάσης αλλά μόνο οι δημόσιες (public) μέθοδοι που υλοποιεί. * **Επαναχρησιμοποίση κώδικα:** Η κλάση σχεδιάζεται έτσι ώστε να μπορεί να επαναχρησιμοποιηθεί και σε άλλα προγράμματα. * **Επεκτασιμότητα:** Η κλάση μπορεί να επεκταθεί μέσω της κληρονομικότητας σε πιο ειδικές κλάσεις. * **Ευκολότερη αποσφαλμάτωση:** Κατά την αποσφαλμάτωση ο αρχικός έλεγχος μπορεί να γίνει σε επίπεδο κλάσης (**Unit testing**). Αλλαγές σε μία κλάση δεν συνεπάγονται αλλαγές και σε άλλα σημεία του προγράμματος που χρησιμοποιούν την κλάση αυτή. * **Μία ομάδα προγραμματιστών μπορεί να εργαστεί παράλληλα:** * Ορίζεται ο τρόπος με τον οποίο επικοινωνούν οι κλάσεις μεταξύ τους. * Κάθε προγραμματιστής ή ομάδα υλοποιεί τις επιμέρους κλάσεις που του/της ανατίθενται. * Ο έλεγχος και η αποσφαλμάτωση του κώδικα σε μεγάλο βαθμό γίνεται διακριτά ανά κλάση ή ομάδα κλάσεων. * Εάν μία κλάση δεν είναι καλά σχεδιασμένη ή υλοποιημένη μπορούμε να την ξαναγράψουμε από την αρχή χωρίς να επηρεαστεί ο υπόλοιπος κώδικας, με την προϋπόθεση ότι δεν αλλάζει ο τρόπος με τον οποίο επικοινωνεί με τις υπόλοιπες κλάσεις. * Στον αντικειμενοστραφή προγραμματισμό η φάση του σχεδιασμού είναι εξαιρετικά σημαντική. Καλός σχεδιασμός σημαίνει συντηρήσιμος, ευκολότερος στην ανάπτυξη κώδικας. | Επόμενο: [[:java:class | Η κλάση]]|

oop/introduction.1436089446.txt.gz · Last modified: 2016/02/26 11:15 (external edit)