Κληρονομικότητα
Εισαγωγή Κληρονομικότητα (Inheritance) καλείται ο μηχανισμός με τον οποίο μία νέα κλάση που ονομάζεται παράγωγη (derived class) δημιουργείται από μία άλλη κλάση που ονομάζεται κλάση βάσης (base class), απορροφώντας ιδιότητες και συμπεριφορά Μια παράγωγη κλάση αυτομάτως “κληρονομεί” όλα τα μέλη δεδομένων και τις μεθόδους της βασικής κλάσης Μία παράγωγη κλάση μπορεί να έχει επιπρόσθετα μέλη δεδομένων ή/και μεθόδους Η παράγωγη κλάση είναι ένα παιδί (child) της βασικής ή γονικής (parent) κλάσης
Κλάσεις Υπαλλήλων Για τη σχεδίαση ενός προγράμματος τήρησης αρχείου με εγγραφές για Τεχνικούς και Διοικητικούς Υπαλλήλους... Και οι δύο κατηγορίες υπαλλήλων ανήκουν σε μία κατηγορία ατόμων με κοινή την ιδιότητα του "Υπαλλήλου" Ένα υποσύνολο των υπαλλήλων είναι οι Τεχνικοί (αμείβονται με την ώρα) Ένα άλλο υποσύνολο των υπαλλήλων είναι οι Διοικητικοί (αμείβονται με το μήνα + ενδεχόμενο bonus) Όλοι οι Υπάλληλοι έχουν ένα όνομα και ΑΦΜ Οι μέθοδοι για τον χειρισμό του ονόματος και του ΑΦΜ είναι κοινές για τις δύο ομάδες υπαλλήλων
Βασική Κλάση Θα ορίσουμε μία κλάση που ονομάζεται Employee για όλους τους υπαλλήλους, η οποία θα ενσωματώνει τα κοινά τους χαρακτηριστικά Η κλάση Employee θα χρησιμοποιηθεί ως βασική κλάση για τον ορισμό των Τεχνικών και Διοικητικών υπαλλήλων Ορισμός βασικής κλάσης Employee Διασύνδεση: Employee.h Υλοποίηση: Employee.cpp
Μέθοδος printCheck Η μέθοδος printCheck θα έχει διαφορετική υλοποίηση για κάθε είδος Υπαλλήλου Ένα αντικείμενο της κλάσης Employee δεν έχει την κατάλληλη πληροφορία για να εκτυπώσει ένα check Η κατάλληλη πληροφορία θα περιέχεται στις παράγωγες κλάσεις
Κλάση Technician Η Technician παράγεται από την κλάση Employee Η κλάση Technician κληρονομεί όλα τα μέλη δεδομένων και τις μεθόδους της κλάσης Employee Ο ορισμός της κλάσης ξεκινά με: class Technician : public Employee :public Employee υποδηλώνει ότι η Technician παράγεται από την Employee (ή κληρονομεί την Employee) H κλάση Technician δηλώνει τις επιπλέον ιδιότητες wageRate (ωριαία αμοιβή) και hours (ώρες εργασίας)
Κληρονομούμενα Μέλη Μία παράγωγη κλάση κληρονομεί όλα τα μέλη της γονικής κλάσης Η παράγωγη κλάση δεν χρειάζεται να επανα- δηλώσει ή επανα-ορίσει μέλη που κληρονομούνται από την κλάση βάσης, εκτός … Η παράγωγη κλάση επαναδηλώνει και επαναορίζει μεθόδους της βασικής κλάσης οι οποίες θα έχουν διαφορετική υλοποίηση στην παράγωγη κλάση Η παράγωγη κλάση μπορεί να προσθέσει τόσο μεθόδους όσο και μέλη δεδομένων
Υλοποίηση σε Παράγωγη Κλάση Κάθε μέθοδος που προστίθεται στην παράγωγη κλάση ορίζεται στο αρχείο υλοποίησης (.cpp) της αντίστοιχης κλάσης Ορισμοί δεν δίνονται για μεθόδους που κληρονομούνται αλλά δεν τροποποιούνται Πρόγραμμα...
Κλάση AdminEmployee Η κλάση AdminEmployee παράγεται επίσης από την Εmployee Η μέθοδος printCheck επαναορίζεται ώστε να έχει σημασία που έχει νόημα για τους υπαλλήλους με μηνιαία αμοιβή Η AdminEmployee προσθέτει μία ιδιότητα bonus
Γονικές κλάσεις και απόγονοι Μία παράγωγη κλάση υπενθυμίζεται ότι αυτομάτως διαθέτει όλες τις μεθόδους και ιδιότητες της γονικής κλάσης Η γονική κλάση είναι πρόγονος (ancestor) της παράγωγης κλάσης Η παράγωγη κλάση είναι απόγονος (descendent) της γονικής κλάσης Η γονική κλάση (Employee) περιλαμβάνει τον κώδικα που είναι κοινός σε όλες τους απογόνους Κατ’ αυτόν τον τρόπο δεν χρειάζεται να ξαναγραφτεί ο κώδικας για κάθε παράγωγη κλάση
Τύποι Παραγόμενων Κλάσεων είναι Ένας Τεχνικός υπάλληλος με ωριαία αμοιβή (Technician) είναι ένας Υπάλληλος (Employee) Στη C++, ένα αντικείμενο τύπου Technician μπορεί να χρησιμοποιηθεί οπουδήποτε μπορεί να χρησιμοποιηθεί και ένα αντικείμενο τύπου Employee Ένα αντικείμενο ενός τύπου κλάσης, μπορεί να χρησιμοποιηθεί οπουδήποτε μπορεί να χρησιμοποιηθεί κάποιος από τους προγόνους της κλάσης δεν μπορεί Ένας πρόγονος δεν μπορεί να χρησιμοποιηθεί οπουδήποτε χρησιμοποιείται ένας απόγονος
Κατασκευαστές Παράγωγων Κλάσεων Ο κατασκευαστής της βασικής κλάσης δεν κληρονομείται από την παράγωγη κλάση Ο κατασκευαστής της βασικής κλάσης μπορεί να κληθεί από τον κατασκευαστή της παράγωγης κλάσης Ο κατασκευαστής μιας παράγωγης κλάσης ξεκινά καλώντας τον κατασκευαστή της βασικής κλάσης στο τμήμα αρχικοποίησης: Techician::Technician(string text, string number) : Employee(text, number) { //no code needed } Οποιοσδήποτε κατασκευαστής μπορεί να κληθεί
Εξ’ ορισμού αρχικοποίηση Αν μία παράγωγη κλάση δεν καλέσει τον κατασκευαστή της βασικής κλάσης ρητά, καλείται ο εξ’ ορισμού κατασκευαστής της βασικής κλάσης Αν η κλάση B παράγεται από τη A και η κλάση C παράγεται από την B: Όταν δημιουργείται ένα αντικείμενο της C Καλείται πρώτα ο κατασκευαστής της A Στη συνέχεια καλείται ο κατασκευαστής της B H εκτέλεση ολοκληρώνεται με τον κατασκευαστή της C
Private is Private Μία ιδιότητα (ή μέθοδος) η οποία είναι ιδιωτική (private) στην γονική κλάση, δεν είναι προσπελάσιμη από την παράγωγη κλάση Οι μέθοδοι της γονικής κλάσης πρέπει να χρησιμοποιηθούν για την προσπέλαση των ιδιωτικών μελών δεδομένων της γονικής κλάσης Ο κάτωθι κώδικας δεν είναι έγκυρος: void Technician::printCheck( ) { income = hours * wage_rage; Η income είναι ιδιωτικό μέλος της Employee!
Ο προσδιοριστής protected Τα protected μέλη μιας κλάσης εμφανίζονται ως ιδιωτικά εκτός της κλάσης, αλλά είναι προσπελάσιμα από τις παράγωγες κλάσεις Αν οι ιδιότητες name, income, και AFM δηλωθούν ως protected (όχι private) στην κλάση Employee ο κάτωθι κώδικας, που ήταν μη έγκυρος, γίνεται απολύτως επιτρεπτός: Technician::printCheck( ) { income = hours * wage_rage;
Programming Style Η χρήση protected μελών μιας κλάσης είναι δυνατότητα που παρέχεται για την διευκόλυνση συγγραφής κλάσεων. Τα Protected μέλη δεν είναι απαραίτητα Οι παράγωγες κλάσεις μπορούν να χρησιμοποιούν τις public μεθόδους των προγόνων τους για να προσπελάσουν ιδιωτικά μέλη Πολλοί experts του προγραμματισμού θεωρούν έλλειψη προγραμματιστικού στυλ τη χρήση των προστατευμένων (protected) μελών
Επανα-ορισμός μεθόδων Κατά τον ορισμό μιας παράγωγης κλάσης παρατίθενται μόνο οι κληρονομούμενες μέθοδοι που είναι επιθυμητό να τροποποιηθούν Η μέθοδος δηλώνεται στον ορισμό της κλάσης Οι Technician και AdminEmployee έχουν τους δικούς τους ορισμούς της printCheck
Επικάλυψη και Υπερφόρτωση Μία μέθοδος που επαναορίζεται/επικαλύπτεται (redefined/overrided) σε μία παράγωγη κλάση έχει τον ίδιο αριθμό και τύπο παραμέτρων Η παράγωγη κλάση έχει μόνο μία μέθοδο με το ίδιο όνομα όπως η βασική κλάση Μία μέθοδος που υπερφορτώνεται (overloaded) έχει διαφορετικό αριθμό και/ή τύπο παραμέτρων από ότι η βασική κλάση Η παράγωγη κλάση έχει δύο (ή περισσότερες) μεθόδους με το ίδιο όνομα όπως η βασική κλάση Η μία ορίζεται στη βασική κλάση, η άλλη στην παράγωγη
Υπογραφές Συναρτήσεων Η υπογραφή μιας συνάρτησης (function signature) είναι το όνομα της συνάρτησης με την ακολουθία των τύπων στη λίστα παραμέτρων Αν μία μέθοδος έχει το ίδιο όνομα σε μία παράγωγη κλάση με μία μέθοδο της βασικής κλάσης αλλά έχει διαφορετική υπογραφή, πρόκειται για υπερφόρτωση όχι επαναορισμό
Πρόσβαση σε μία επαναορισμένη μέθοδο της βασικής κλάσης Όταν μία μέθοδος της βασικής κλάσης επαναορίζεται σε μία παράγωγη κλάση, η μέθοδος της βασικής κλάσης μπορεί πάλι να χρησιμοποιηθεί Για να προσδιορίσετε ότι θέλετε να χρησιμοποιήσετε την έκδοση της βασικής κλάσης : Technician sally_h; sally_h.Employee::printCheck( );