7η Ενότητα Κληρονομικότητα Εισαγωγή Ιεραρχία κλάσεων – παραδείγματα Σχέσεις και Κληρονομικότητα Βασικά χαρακτηριστικά της κληρονομικότητας Είδη κληρονομικότητας Constructors και κληρονομικότητα Επανακαθορισμός συναρτήσεων Κληρονομικότητα πολλών επιπέδων ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
1. Εισαγωγή Οι κλάσεις καθορίζουν τις ιδιότητες και τη συμπεριφορά σε σύνολα αντικειμένων. Οι κλάσεις συχνά χρησιμοποιούνται ιεραρχικά δηλαδή μια κλάση (υπερκλάση) είναι μια γενίκευση μιας ή περισσοτέρων άλλων κλάσεων (υποκλάσεις). Π.χ. : η κλάση για ένα αυτοκίνητο μπορεί να περιέχει τις εξής υποκλάσεις : Αμάξωμα Κινητήρας Σύστημα μετάδοσης κίνησης Σύστημα ανάρτησης Εσωτερικό ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κάθε μια από τις κλάσεις αυτές μπορεί να περιέχει τις δικές της υποκλάσεις. π.χ. ο κινητήρας μπορεί να περιλαμβάνει : τη συσκευή ανάμειξης αέρα/καυσίμου (καρμπιρατέρ), τα έμβολα, τους κυλίνδρους, τους σπινθηριστές (μπουζί) κλπ. Η κλάση αυτοκίνητο αναφέρεται ως η κλάση γονέας (parent class) ή υπερκλάση (super class). ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Η ιεραρχία των κλάσεων ξεκινά από την κλάση γονέα που δεν περιλαμβάνει ιδιαίτερες λεπτομέρειες και συνεχίζει προς τα κάτω όπου οι λεπτομέρειες είναι περισσότερες. Αυτό σημαίνει ότι : η κλάση γονέας είναι μια γενίκευση των υποκλάσεων η υποκλάση είναι μια εξειδίκευση της κλάσης γονέα. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Η κληρονομικότητα είναι το δεύτερο βασικό χαρακτηριστικό στον αντικειμενοστραφή προγραμματισμό, μετά από τις κλάσεις. Αποτελεί την κινητήρια δύναμη του αντικειμενοστραφούς προγραμματισμού, καθιστώντας δυνατή την επαναχρησιμοποίηση μιας κλάσης που έχει δημιουργηθεί σε ένα πρόγραμμα. Η επαναχρησιμοποίηση έτοιμων κλάσεων μειώνει τον χρόνο και την προσπάθεια για την ανάπτυξη ενός νέου προγράμματος και καθιστά το λογισμικό περισσότερο αξιόπιστο. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Reusability (επαναχρησιμοποίηση) Οι προγραμματιστές επεδίωκαν πάντοτε να μη ξαναγράφουν τον ίδιο κώδικα. Η μερική τροποποίηση υπάρχοντος κώδικα σε νέα προγράμματα δημιουργεί λάθη. Function libraries (συναρτήσεις βιβλιοθήκης) Συναρτήσεις γενικής χρήσης ενσωματώνονται σε ένα αρχείο. Μειονέκτημα : ΔΕΝ απεικονίζουν την πραγματικότητα εφόσον δεν περιλαμβάνουν τα πραγματικά δεδομένα. Συνήθως χρειάζονται τροποποίηση για να χρησιμοποιηθούν σε νέα προγράμματα. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Class Libraries (βιβλιοθήκες κλάσεων) Μία κλάση απεικονίζει με καλύτερο τρόπο την πραγματικότητα. Χρειάζεται λιγότερες τροποποιήσεις για να χρησιμοποιηθεί εκ νέου. Ο αντικειμενοστραφής προγραμματισμός παρέχει ένα νέο τρόπο για την τροποποίηση μιας κλάσης χωρίς να αλλάξει ο κώδικας (source code). Αυτή η φαινομενική αντίφαση προκύπτει από τη δυνατότητα να παραχθεί μια νέα κλάση από μια παλιά. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
2. Ιεραρχία κλάσεων - παραδείγματα Vehicle Wheeled vehicle Boat Car Bicycle 2-door 4-door ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
μουσικά formats Music Format Analog Format Digital Format Magnetic Tape Vinyl DAT Disk MP3 12” Record 7” Record MiniDISC CD ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Μέλη της Πανεπιστημιακής κοινότητας Employee CommunityMember Student Faculty Staff Administrator Teacher ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Γεωμετρικά σχήματα Shape TwoDimensionalShape ThreeDimensionalShape Circle Square Triangle Sphere Cube Tetrahedron ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κτήρια Building Commercial Public Domestic Office block Apartment Factory Cathedral Hospital ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Η κληρονομικότητα στον αντικειμενοστραφή προγραμματισμό απεικονίζει την αρχή της γενίκευσης στον πραγματικό κόσμο. π.χ. ένα αγωνιστικό ποδήλατο, ένα mountain bike και ένα παιδικό ποδήλατο είναι όλα στιγμιότυπα μιας γενικής έννοιας που είναι το ποδήλατο. Κάθε είδος ποδηλάτου έχει 2 τροχούς, σκελετό, τιμόνι κλπ. Το αγωνιστικό ποδήλατο έχει ΕΠΙΠΛΕΟΝ λεπτούς τροχούς και μικρό βάρος Το mountain bike έχει διογκωμένα λάστιχα και ισχυρά φρένα ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Οι γενικεύσεις χρησιμοποιούνται ως αντίληψη καθημερινά στον κόσμο π.χ. Φορτηγά, λεωφορεία και αυτοκίνητα είναι στιγμιότυπα οχημάτων Εργάτες, γραμματείς, επιστήμονες είναι στιγμιότυπα εργαζομένων Η κληρονομικότητα στον αντικειμενοστραφή προγραμματισμό δεν αντιστοιχεί ακριβώς στην έννοια που ξέρουμε για τις οικογένειες. Μια κλάση μπορεί να παραχθεί μόνον από ένα γονέα και έχει περισσότερα χαρακτηριστικά από αυτά του γονέα σε σχέση με τα χαρακτηριστικά που μεταφέρουν οι απόγονοι από τους προγόνους τους στις οικογένειες. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Ιεραρχία κλάσεων Η ιεραρχία κλάσεων ενσωματώνει και συστηματοποιεί τόσο τις ομοιότητες όσο και τις διαφορές μεταξύ των αντικειμένων. Η δημιουργία της λύσης με τους ίδιους όρους που θέτει το πρόβλημα είναι εξαιρετικά ωφέλιμο επειδή δεν χρειάζεται ένα πλήθος ενδιάμεσων μοντέλων για τη μετάβαση από την περιγραφή του προβλήματος σε αυτήν της λύσης. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
3. Σχέσεις (RELATIONSHΙPS) και Κληρονομικότητα (INHERITANCE) Υπάρχουν τρεις τύποι σχέσεων μεταξύ των κλάσεων : η κληρονομικότητα, η συσσώρευση (aggregation) και η συσχέτιση (association). ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κληρονομικότητα Η κληρονομικότητα καθορίζεται συνήθως από την έκφραση «είναι ένα είδος από» (“is a” or “ is a kind of” relationship). Για παράδειγμα: το επαγγελματικό αυτοκίνητο και το αυτοκίνητο ιδιωτικής χρήσης είναι του είδους αυτοκίνητο και συνεπώς κληρονομούν από την κλάση αυτοκίνητο. Οι σχέσεις αυτού του τύπου χρησιμοποιούνται σε επίπεδο κλάσης για να περιγράψουν σχέσεις ανάμεσα σε δύο παρόμοιες κλάσεις. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
TRUCKS CARS VEHICLES “is-a” Relationship ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
is a is a Vehicle “is-a” Relationship Each car is a vehicle Class car is a subclass of the class of vehicle class car: public vehicle is a is a Vehicle ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
‘A kind of’ or ‘a part of’? Vehicle Car A car is ‘a kind of’ vehicle car class can inherit from vehicle class ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Συσσώρευση (aggregation) Η συσσώρευση προσδιορίζεται από την έκφραση «είναι τμήμα του/της» (“has a” OR “ a part of” relationship) όπως π.χ. ο κινητήρας είναι τμήμα του αυτοκινήτου. Οι συσχετίσεις αυτές χρησιμοποιούνται για την κατασκευή αντικειμένων (ή κλάσεων) μέσω του συνδυασμού άλλων αντικειμένων (ή κλάσεων). Η διαδικασία αυτή είναι παρόμοια με τη δομή (struct) στο διαδικαστικό προγραμματισμό, όπου η δομή δημιουργείται από τη συσσώρευση δεδομένων διαφορετικών τύπων. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
CAR MOTOR “Has-a” Relationship ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
‘A kind of’ or ‘a part of’? A car is ‘a kind of’ vehicle car class can inherit from vehicle class Vehicle Car A wheel isn’t ‘a kind of’ car. A wheel is ‘a part of’ a car Car Wheel ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
“Has-a” Relationship class car The car contains a motor { // . . . . { // . . . . private: Motor engine; }; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Συσχέτιση Αν δεν εφαρμόζεται καμία από τις δύο πρώτες σχέσεις, αλλά τα αντικείμενα είναι σαφώς συσχετισμένα (όπως π.χ. ένα αυτοκίνητο επαγγελματικής χρήσης ανήκει σε μια μεταφορική εταιρεία) η σχέση είναι η συσχέτιση. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα συσχετίσεων Θεωρείστε τις κλάσεις : Student Person Name Address Professor Ποιες οι συσχετίσεις μεταξύ τους; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
is is has has Student Professor Person Name Address ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Ο τελεστής συσχέτισης κλάσεων : class Name { // . . . . char last[20]; char first[15]; }; class Address { char street[20]; char city[10]; char state[3]; }; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Class Person class Person { // . . . . Name person_name; { // . . . . Name person_name; Address person_address; }; class Student: public Person char major[10]; int id; int level; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Class Professor: public Person { // . . . . float salary; }; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Διαφορετικές κλάσεις ή διαφορετικές καταστάσεις; Απαιτείται ανάλυση ώστε να αποσαφηνιστεί αν οι διαφορές μεταξύ των αντικειμένων απορρέουν από τον τύπο τους (όπως π.χ. μια κατοικία είναι διαφορετική από ένα εργοστάσιο) ή από την κατάστασή τους (διαφορετικές τιμές των χαρακτηριστικών της κλάσης) Χαμηλά και υψηλά κτήρια διαφέρουν μόνο στη τιμή του ύψους – είναι data member της κλάσης – ΔΕΝ ΑΠΑΙΤΟΥΝΤΑΙ ΞΕΧΩΡΙΣΤΕΣ ΚΛΑΣΕΙΣ Building Short Building Tall Building ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
4. Βασικά χαρακτηριστικά της κληρονομικότητας Η κληρονομικότητα μπορεί να οριστεί ως η διαδικασία κατά την οποία ένα αντικείμενο αποκτά (λαμβάνει) χαρακτηριστικά από ένα ή περισσότερα άλλα αντικείμενα, χωρίς να χρειάζεται η πανομοιότυπη αναπαραγωγή του κληρονομούμενου κώδικα στους απογόνους. Μπορεί επιπλέον να περιέχει πρόσθετα χαρακτηριστικά και να υλοποιεί νέες μεθόδους που δεν υπάρχουν στην κλάση – πρόγονο. Ορισμένα αντικειμενοστραφή συστήματα επιτρέπουν μόνον την απλή κληρονομικότητα όπου μια υποκλάση κληρονομεί χαρακτηριστικά και μεθόδους από έναν μόνο πρόγονο. Ωστόσο τα περισσότερα αντικειμενοστραφή συστήματα επιτρέπουν πολλαπλή κληρονομικότητα όπου μια υποκλάση μπορεί να κληρονομεί από δύο ή περισσότερες κλάσεις – προγόνους οι οποίοι είναι ανεξάρτητοι μεταξύ τους. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Δύο είδη κληρονομικότητας Single Inheritance Multiple Inheritance BASE1 BASE2 BASE3 DerivedA DerivedC DerivedD DerivedB ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Βασικά χαρακτηριστικά (συνέχεια) Η πολλαπλή κληρονομικότητα : είναι ένα ισχυρό αντικειμενοστραφές χαρακτηριστικό που ενισχύει τη διαμοίραση ιδιοτήτων μεταξύ παρόμοιων υποκλάσεων και συνδέει όλες τις κλάσεις σε ένα ιεραρχικό δένδρο με μια μοναδική κλάση ως ρίζα. μπορεί να χρησιμοποιηθεί για την αποτύπωση των ιεραρχικών δομών του πραγματικού κόσμου που είναι πλησιέστερα στο μοντέλο. Συχνά οι υπερκλάσεις δεν αντιπροσωπεύουν καμία από τις οντότητες που υπάρχουν στην εφαρμογή. στον αντικειμενοστραφή προγραμματισμό συνήθως υλοποιείται κατά τη διάρκεια του χρόνου σύνδεσης και έτσι δεν απαιτεί πρόσβαση στον πηγαίο κώδικα της κλάσης - γονέα. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Βασικά χαρακτηριστικά (συνέχεια) Επειδή η κληρονομικότητα είναι σημαντική στην αντικειμενοστραφή προσέγγιση συχνά τονίζεται υπέρμετρα και μπορεί κάποιος να θεωρήσει ότι αυτή μπορεί να χρησιμοποιηθεί οπουδήποτε. Αυτό μπορεί να έχει ως αποτέλεσμα άτεχνους και υπέρ-σύνθετους σχεδιασμούς. Αντ’ αυτού θα ήταν προτιμότερο να γίνει μια πρώτη προσέγγιση στη σύνθεση νέων κλάσεων, ώστε να παραχθούν απλούστερα και καθαρότερα σχέδια. Η εμπειρία είναι ο σημαντικότερος παράγοντας που καθορίζει πότε πραγματικά χρειάζεται η κληρονομικότητα. Οι σχέσεις κληρονομικότητας θα πρέπει να καθοριστούν κατά τη διάρκεια ενός προκαταρκτικού σχεδιασμού και να επιβεβαιωθούν στη συνέχεια κατά τη διάρκεια λεπτομερούς σχεδιασμού καθώς αποτελούν πρωτεύοντες μηχανισμούς για τη μεγιστοποίηση της εκ νέου χρήσης του κώδικα. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Βασικά χαρακτηριστικά (συνέχεια) είναι ένας αφαιρετικός μηχανισμός που μπορεί να χρησιμοποιηθεί για την ταξινόμηση οντοτήτων επιτρέπει την επαναχρησιμοποίηση σε επίπεδο σχεδιασμού και προγραμματισμού και προσαρμόζεται εύκολα σε μεταβολές το γράφημα κληρονομικότητας, που προκύπτει από τη σχεδίαση της ιεραρχίας των κλάσεων, είναι μια πηγή γνώσης σχετικά με την οργάνωση των συστημάτων ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Προβλήματα οι κλάσεις αντικειμένων δεν είναι ανεξάρτητες και δεν μπορούν να γίνουν κατανοητές δίχως αναφορά στις υπερκλάσεις τους. οι σχεδιαστές των συστημάτων έχουν την τάση να χρησιμοποιούν υπερβολικά το γράφημα κληρονομικότητας που έχει δημιουργηθεί κατά τη διάρκεια της ανάλυσης γεγονός που μπορεί να οδηγήσει σε σημαντική μείωση της αποδοτικότητας τα γραφήματα κληρονομικότητας για την ανάλυση, τον σχεδιασμό και την υλοποίηση έχουν διαφορετικές συναρτήσεις (λειτουργίες) και θα πρέπει να διατηρούνται ξεχωριστά. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Ορισμοί & χαρακτηριστικά Η βασική κλάση (ονομάζεται base class), δεν τροποποιείται, αλλά η νέα κλάση (ονομάζεται derived class – παραγόμενη ή απορρέουσα κλάση) μπορεί να χρησιμοποιεί όλα τα χαρακτηριστικά της παλιάς καθώς και νέα δικά της χαρακτηριστικά (data members και member functions). Η δημιουργία μιας απορρέουσας κλάσης δεν επηρεάζει τον πηγαίο κώδικα της βασικής κλάσης. Η ακεραιότητα της βασικής κλάσης προστατεύεται από την κληρονομικότητα. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πότε μπορεί να χρησιμοποιηθεί η κληρονομικότητα; Object-Oriented Design guideline: If two or more classes have common data and behavior, then those classes should inherit from a common base class that captures those data and methods ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
5. Είδη κληρονομικότητας Κληρονομικότητα (Inheritance) Απλή (Single Inheritance) Η κλάση κληρονομεί από μια βασική κλάση Πολλαπλή (Multiple Inheritance) Η κλάση κληρονομεί από πολλές βασικές κλάσεις Τύποι: public: private: protected: Οι απορρέουσες και οι φιλικές κλάσεις (derived classes and friends) μπορούν να έχουν πρόσβαση στα protected members της βασικής κλάσης ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Βασική και απορρέουσες κλάσεις - παραδείγματα ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
base class Vehicle wheels engine Car Truck wheels engine trunk wheels trailer sub-classes or derived classes trunk trailer ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
base class Vehicle brake() start_engine() Car Truck brake() open_door() brake() start_engine() open_door() sub-classes or derived classes open_door() pull_trailer() ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παραδείγματα class Shape { class Triangle: public Shape { protected: int width, height; public: void setDims (int a, int b){ width=a; height=b;} }; class Triangle: public Shape { public: int area ( ) { return (width * height/2); } }; class Rectangle: public Shape { public: int area ( ) { return (width * height); } }; class Square: public Rectangle { public: void setDims (int a){ width=a; height=a;} }; ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Ιεραρχία κλάσεων –παράδειγμα : Student Class student_id, year, name print() year_group() inherits (is a relationship) grad_student dept, thesis print() Παράδειγμα : inher-01.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πλεονεκτήματα της κληρονομικότητας Όταν μια κλάση κληρονομεί από μια άλλη κλάση υπάρχουν τρία βασικά οφέλη : οι μέθοδοι και τα δεδομένα της υπάρχουσας κλάσης μπορούν να επαναχρησιμοποιηθούν. η υπάρχουσα κλάση μπορεί να επεκταθεί με την προσθήκη νέων μεθόδων και δεδομένων Η υπάρχουσα κλάση μπορεί να τροποποιηθεί με υπερφόρτωση (overloading) των μεθόδων της με νέες υλοποιήσεις ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Συντακτικό στην κληρονομικότητα (1) Η απλούστερη περίπτωση απαιτεί δύο κλάσεις : την base class και την derived class. H base class δεν απαιτεί κάποιο ιδιαίτερο συντακτικό. Η derived class πρέπει να δείχνει ότι είναι απορρέουσα. Μετά από το όνομά της ακολουθεί ο τελεστής : , η λέξη public και το όνομα της βασικής κλάσης (base class) ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Συντακτικό στην κληρονομικότητα (2) class derivedClass : public baseClass { private : // Declarations of additional members, if needed. public: protected: } The derived class inherits from the base class: all public members, all protected members (see later), and the default constructor The additional members defined can have the same name (and type) αs those of the base class (as when some base members are to be redefined) ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Συντακτικό στην κληρονομικότητα (3) class derivedClass : protected baseClass { …}; // Effect: all public members inherited from baseClass are // now protected members of derivedClass class derivedClass : private baseClass { …}; // Effect: all public and protected members inherited from // baseClass are now private members of derivedClass Multiple inheritance A class can inherit several classes at once: class derivedClass:public baseClass1,public baseClass2 { …}; Remark: Not recommended ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα class Base { // member data and functions }; class Derv : public Base Παραδείγματα : inher-02.cpp, inher-03.cpp Access specifier ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κάθε αντικείμενο που ανήκει στην απορρέουσα κλάση κληρονομεί όλα τα μέλη (δεδομένα και συναρτήσεις) της βασικής κλάσης. Τα private members της βασικής κλάσης δεν είναι άμεσα προσπελάσιμα από member functions της απορρέουσας κλάσης (δεν κληρονομείται η πρόσβαση στα private data members της βασικής κλάσης) Παράδειγμα : inher-04.cpp Error :cannot access private member declared in class 'Parent‘ see declaration of 'flov' ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πίνακας κληρονομικότητας Property Public Inheritance Protected Inheritance Private Inheritance Public members become… Public members of the derived class Protected members of the derived class Private members of the derived class Protected members become… Private members become… Accessible only through the base class interface ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Three Types of Inheritance Access level of members will be changed by derivation. (private parts will always be invisible in derived class.) “public” inheritance Base Derived private (invisible) protected protected public public “private” inheritance protected private public private “protected” inheritance public protected protected, public parts will be unchanged protected, public parts will be private protected, public parts will be protected ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
public Inheritance main() { Derived a; a.x = 1; // error class Base { a.y = 2; // error a.z = 3; // OK } class Base { private: int x; protected: int y; public: int z; void func() { x = 1; // OK (accessed in member func.) y = 2; // OK (accessed in member func.) z = 3; // OK } }; class Derived : public Base { x = 1; // error (invisible from outside of Base) y = 2; // OK (accessed in member func. in derived class) z = 3; // OK } ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
private Inheritance class Derived2 : Derived1 { class Base { (same as private inheritance) class Derived2 : Derived1 { void func() { x = 1; // error (invisible outside of Base) y = 2; // error (behaves as if ‘private’ in Derived1) z = 3; // error } }; class Base { private: int x; protected: int y; public: int z; void func() { x = 1; // OK (accessed in member func.) y = 2; // OK z = 3; // OK } }; class Derived1 : private Base { x = 1; // error (invisible from outside of Base) y = 2; // OK (accessed in member func. in derived class) z = 3; // OK } ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
protected Inheritance class Derived2 : Derived1 { void func() { x = 1; // error (invisible outside of Base) y = 2; // OK (behaves as if ‘protected’ in Derived1) z = 3; // OK } }; class Base { private: int x; protected: int y; public: int z; void func() { x = 1; // OK (accessed in member func.) y = 2; // OK (accessed in member func.) z = 3; // OK } }; class Derived1 : protected Base { x = 1; // error (invisible from outside of Base) y = 2; // OK (accessed in member func. in derived class) z = 3; // OK } ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Υπερφόρτωση συναρτήσεων Παραδείγματα : inher-05.cpp inher-06.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κανόνες για την κατασκευή της ιεραρχίας κλάσεων Οι απορρέουσες κλάσεις είναι ΕΙΔΙΚΕΣ ΠΕΡΙΠΤΩΣΕΙΣ των βασικών κλάσεων. Μια απορρέουσα κλάση μπορεί να αποτελέσει βασική κλάση για κάποια άλλη κλάση. Δεν υπάρχει κάποιο πρακτικό όριο για το βάθος της κληρονομικότητας στη C++ (αν και εξαρτάται από τον compiler). Είναι δυνατό μια κλάση να είναι η βασική κλάση για περισσότερες από μία απορρέουσες κλάσεις. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
6. Constructors και κληρονομικότητα (1) Ο constructor της βασικής κλάσης εκτελείται πρώτος, για να γίνει η αρχικοποίηση των data members της βασικής κλάσης και στη συνέχεια εκτελείται ο constructor της απορρέουσας κλάσης. Όταν ορίζουμε ένα αντικείμενο στην απορρέουσα κλάση τότε εκτελείται όχι μόνον ο constructor της απορρέουσας κλάσης αλλά και ο constructor της βασικής κλάσης. Στο τέλος οι destructors καλούνται με αντίθετη σειρά δηλ. πρώτα της απορρέουσας και μετά της βασικής κλάσης Παράδειγμα : inher-07.cpp, inher-21.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Constructors και κληρονομικότητα (2) Αν ο constructor της βασικής κλάσης έχει παραμέτρους τότε κάθε απορρέουσα κλάση υποχρεούται να δηλώνει έναν constructor με τις ίδιες ακριβώς παραμέτρους. Τα ορίσματα που δίνονται στον constructor της απορρέουσας κλάσης μπορούν να μεταβιβαστούν στον constructor της βασικής κλάσης. Δεν μπορεί να χρησιμοποιηθεί ένας constructor με ορίσματα αν προηγουμένως δεν έχει ρητά οριστεί στην κλάση από την οποία ένα αντικείμενο προσδιορίζεται άμεσα. Η κλήση του κατάλληλου και ορθού constructor είναι ευθύνη του προγραμματιστή. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα class Customer { Customer (char * name_in); … } Base class declares a constructor that takes a char pointer parameter class Customer { Customer (char * name_in); … } Class AccountCustomer:public Customer AccountCustomer(char * name_in); .. Derived class declares a constructor that takes the same char pointer parameter ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα This class has a constructor class creature { private: int yearOfBirth; public: creature(int YOB); int getYearOfBirth(); }; int main() creature myCreature(1985); cout << "my creature was born in " << myCreature.getYearOfBirth() <<endl; return 0; } This class has a constructor that takes an integer argument. When instantiating an object of this class you pass a parameter to the constructor. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα class Student { private: long number_; float average_grade_; public: Student() :number_(0),average_grade_(0.0f) { } Student(long number, float average_grade) : number_(number),average_grade_(average_grade) .... ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
// constructor of the derived class class StudentWithAccount : public Student { private: double balance_; public: StudentWithAccount(long, float, double = 0.0); // constructor of the derived class StudentWithAccount:: StudentWithAccount(long number, float average, double balance) : Student(number, average), // base class' constructor balance_(balance) // init list of derived class {} ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Constructors και κληρονομικότητα (3) Παραδείγματα: inher-08.cpp , inher-09.cpp Στο παράδειγμα inher-09.cpp ο constructor Β_class(int) καλεί τον base class constructor Α_class(int) χρησιμοποιώντας σύνταξη ανάλογη με την constructor’s initialization list που χρησιμοποιείται για τα data members μιας απλής κλάσης (μετά από το όνομα του constructor υπάρχουν : και ακολουθούν τα ονόματα των data members έχοντας σε παρένθεση τις μεταβλητές που θα χρησιμοποιηθούν για την αρχικοποίηση όταν κληθεί ο constructor στο αντίστοιχο object της κλάσης). Παρaδείγματα : inher-10.cpp, inher-19.cpp, inher-20.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Κληρονομικότητα και δυνατότητα πρόσβασης Παράδειγμα: inher-11.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
7. Επανακαθορισμός συναρτήσεων Όσα πρωτότυπα δεν καθορίζονται εκ νέου έχουν τον ίδιο ορισμό στην απορρέουσα κλάση όπως και στη βασική. Τα μοναδικά πρωτότυπα από τη βασική κλάση που συμπεριλαμβάνονται στην απορρέουσα κλάση είναι οι συναρτήσεις που αλλάζουν ορισμό. Όταν μια member function επανακαθορίζεται το πρωτότυπό της πρέπει να εμφανίζεται στη λίστα ορισμού της απορρέουσας κλάσης , ακόμη και αν το πρωτότυπο είναι το ίδιο όπως και στη βασική κλάση. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Επανακαθορισμός – Υπερφόρτωση (1/2) Δεν πρέπει να συγχέονται οι όροι overriding (redefining) και overloading (αποδίδονται ως επανακαθορισμός και υπερφόρτωση). Όταν μια συνάρτηση επανακαθορίζεται , η νέα μορφή της συνάρτησης στην απορρέουσα κλάση έχει ακριβώς τον ίδιο αριθμό και τύπο παραμέτρων. Αν υπάρχει μια νέα συνάρτηση με το ίδιο όνομα αλλά με διαφορετικό αριθμό παραμέτρων ή με διαφορετική σειρά τύπων (ή και τα δύο μαζί) τότε η απορρέουσα κλάση θα έχει και τις δύο συναρτήσεις (overloading). ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Επανακαθορισμός – Υπερφόρτωση (2/2) Η υπογραφή μιας συνάρτησης είναι το όνομά της με την ακολουθία των τύπων της λίστας παραμέτρων, όπου μπορούν να περιλαμβάνονται και άλλες λέξεις-κλειδιά ή ειδικά σύμβολα (όπως η λέξη const ). Στον επανακαθορισμό συνάρτησης σε απορρέουσα κλάση και οι δύο μορφές (σε απορρέουσα και βασική κλάση) έχουν την ίδια υπογραφή. Αν μια συνάρτηση έχει το ίδιο όνομα στην απορρέουσα κλάση όπως και στη βασική αλλά έχει διαφορετική υπογραφή τότε είναι υπερφορτωμένη (overloaded) και όχι επανακαθοριζόμενη (redefined). ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παραδείγματα Public inheritance Private inheritance Ένα αντικείμενο της απορρέουσας κλάσης μπορεί να χρησιμοποιηθεί αντί για ένα αντικείμενο της βασικής κλάσης. Κάθε αντικείμενο απορρέουσας κλάσης είναι ένα είδος αντικειμένου της βασικής κλάσης. Παράδειγμα : inher-12.cpp Private inheritance Παράδειγμα : inher-13.cpp (εμφανίζει 3 λάθη) ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πρόσβαση από τα μέλη της απορρέουσας κλάσης Private inheritance Protected inheritance Public inheritance Private base class data ΟΧΙ Protected base class data ΝΑΙ Public base class data ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
8. Πολλαπλή Κληρονομικότητα (πολλών επιπέδων) Class DAG για μία τράπεζα DAG : Directed Acyclic Graph ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Στην πολλαπλή κληρονομικότητα μια κλάση μπορεί να έχει περισσότερες από μία υπερκλάσεις. Οι σχέσεις μεταξύ των κλάσεων / υποκλάσεων αναπαρίστανται από ένα κατευθυνόμενο άκυκλο γράφημα ( directed acyclic graph (DAG) ) Η αναπαράσταση αυτή είναι ιδιαίτερα χρήσιμη όταν τα αντικείμενα μπορούν να κατηγοριοποιηθούν με περισσότερους από έναν τρόπους που είναι ανεξάρτητοι μεταξύ τους. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παράδειγμα Παράδειγμα : inher-14.cpp class alpha // first generation { }; class beta : public alpha // second generation class gamma : public beta // third generation class delta : public gamma // fourth generation Κάθε απορρέουσα κλάση έχει πρόσβαση σε όλους τους προγόνους της. Παράδειγμα : inher-14.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Constructors σε κληρονομικότητα πολλών επιπέδων Παράδειγμα : inher-15.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Σύνθεση Είναι η τοποθέτηση ενός αντικειμένου μιας κλάσης μέσα σε ένα αντικείμενο μιας άλλης κλάσης. Παράδειγμα : inher-16.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πολλαπλή κληρονομικότητα Μια απορρέουσα κλάση κληρονομεί από δύο ή περισσότερες βασικές κλάσεις class Base1 { }; class Base2 class Derv : public Base1, public Base2 Παράδειγμα : inher-17.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Πολλαπλή κληρονομικότητα ή σύνθεση; Παράδειγμα : inher-18.cpp ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παρατηρήσεις – οδηγίες (1) Οποιοδήποτε τμήμα κώδικα έχει γραφεί για τη διαχείριση μιας βασικής κλάσης θα λειτουργήσει επίσης με οποιαδήποτε κλάση απορρέει από τη βασική κλάση. Εξ αιτίας της κληρονομικότητας : Ο τύπος της πραγματικής παραμέτρου στην C++ μπορεί να είναι μια κλάση που απορρέει από την κλάση στην οποία ανήκει η τυπική παράμετρος ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παρατηρήσεις – οδηγίες (2) Όταν μια συνάρτηση – μέλος μιας βασικής κλάσης υπερκαλύπτεται σε μια απορρέουσα κλάση, συνήθως η συνάρτηση της απορρέουσας κλάσης καλεί τη συνάρτηση της βασικής κλάσης και γίνεται ακόμη κάτι επιπλέον. Δεν πρέπει να χρησιμοποιείται ο τελεστής εμβέλειας για την αναφορά της συνάρτησης – μέλους της βασικής κλάσης διότι προκαλεί μια ατέρμονη αναδρομή (infinite recursion) που θα οδηγήσει σε άσκοπη δέσμευση μνήμης και τελικά σε ένα σφάλμα εκτέλεσης (fatal execution-time error). ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07
Παρατηρήσεις – οδηγίες (3) Λόγω της κληρονομικότητας η βασική κλάση μπορεί να μεταγλωττιστεί ανεξάρτητα από την απορρέουσα κλάση. Μόνον τα επιπρόσθετα χαρακτηριστικά και μέθοδοι της απορρέουσας κλάσης απαιτείται να μεταγλωττιστούν ώστε να συνδυαστούν με τη βασική κλάση για να δημιουργήσουν μια απορρέουσα κλάση. Οι τροποποιήσεις στη βασική κλάση δεν απαιτούν αλλαγές στις απορρέουσες κλάσεις καθώς οι public και protected διεπαφές με τη βασική κλάση παραμένουν ανέπαφες. Ωστόσο οι απορρέουσες κλάσεις απαιτείται να μεταγλωττιστούν εκ νέου. ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ / 07