inheritance c
Σημασία της κληρονομικότητας στο C ++ με παραδείγματα:
Το κληρονομικό είναι ένα από τα πιο σημαντικά χαρακτηριστικά του αντικειμενοστρεφούς προγραμματισμού.
Κληρονομικότητα είναι η τεχνική με την οποία μια τάξη αποκτά τις ιδιότητες και τις μεθόδους της άλλης τάξης. Με αυτόν τον τρόπο μπορούμε να επαναχρησιμοποιήσουμε τον κώδικα που είναι ήδη γραμμένος και επαληθευμένος. Η κλάση που αποκτά τις ιδιότητες μιας άλλης τάξης ονομάζεται κλάση υποκατηγορίας ή παράγωγης ή θυγατρικής τάξης.
Η τάξη των οποίων οι ιδιότητες αποκτώνται ονομάζεται βασική τάξη ή γονική τάξη ή superclass. Όταν μια κλάση αποκτά ή κληρονομεί μια άλλη τάξη, τότε όλες οι ιδιότητες και οι μέθοδοι της βασικής κατηγορίας είναι διαθέσιμες για την παράγωγη κλάση, έτσι ώστε να μπορούμε να επαναχρησιμοποιήσουμε αυτόν τον κωδικό.
=> Επισκεφθείτε εδώ για να μάθετε C ++ από το μηδέν.
καλύτερο λογισμικό για τη βελτιστοποίηση των Windows 10
Τι θα μάθετε:
- Γιατί χρειαζόμαστε κληρονομικότητα;
- Τρόποι κληρονομικότητας
- Διάταξη Κατασκευαστών / Καταστροφέων Κληρονομικότητας
- Τύποι κληρονομικότητας
- Πρότυπο κληρονομικότητας
- Σύνθεση
- Πώς πρέπει να αποφασίσουμε μεταξύ της σύνθεσης και της κληρονομικότητας;
- συμπέρασμα
- Συνιστώμενη ανάγνωση
Γιατί χρειαζόμαστε κληρονομικότητα;
Εξετάστε μια ομάδα οχημάτων όπως αυτοκίνητο, λεωφορείο, τζιπ κ.λπ. Καθένα από αυτά τα οχήματα θα έχει ιδιότητες και μεθόδους όπως υποδεικνύεται στο παρακάτω διάγραμμα.
Εάν απαιτείται να εφαρμόσουμε μεμονωμένες κατηγορίες για τα παραπάνω οχήματα, μπορούμε να δούμε ότι και στις τρεις κατηγορίες, θα πρέπει να γράψουμε τον ίδιο κωδικό με και τους τρεις τύπους οχημάτων που παρουσιάζουν λίγο πολύ τις ίδιες ιδιότητες. Αυτό θα κάνει το πρόγραμμά μας αναποτελεσματικό και δυσκίνητο, καθώς θα υπάρχει πολύς διπλός κώδικας.
Αντί να γράψουμε διπλό κώδικα όπως παραπάνω, μπορούμε να εφαρμόσουμε τη δυνατότητα κληρονομιάς για να αποτρέψουμε την αναπαραγωγή του κώδικα και επίσης να γράψουμε ένα μόνο κομμάτι κώδικα και να τον χρησιμοποιήσουμε και στις τρεις κατηγορίες. Αυτό απεικονίζεται εικονικά όπως παρακάτω.
Στο παραπάνω σχήμα, έχουμε ορίσει μια βασική κατηγορία 'Οχήματα' και έχουμε εξαγάγει τις κατηγορίες Car, Bus και Jeep από αυτήν την κατηγορία. Οι κοινές μέθοδοι και ιδιότητες αποτελούν μέρος της κλάσης Vehicles τώρα. Καθώς άλλες κατηγορίες προέρχονται από την κατηγορία Vehicles, όλες οι τάξεις αποκτούν αυτές τις μεθόδους και ιδιότητες.
Ως εκ τούτου, πρέπει απλώς να γράψουμε τον κοινό κώδικα μόνο μία και και τις τρεις κατηγορίες. Αυτοκίνητο, λεωφορείο και τζιπ θα το αποκτήσουν.
Έτσι, το βασικό πλεονέκτημα, που αποκτάμε κληρονομούμε τις υπάρχουσες τάξεις ή σχεδιάζουμε μηχανισμό κληρονομιάς είναι η επαναχρησιμοποίηση του κώδικα.
Περαιτέρω ανάγνωση = >> Εκμάθηση κληρονομιάς Java
Η γενική μορφή για την κληρονομική τάξη είναι:
class derived_classname: access_specifier base_classname { };
Εδώ ' deriv_classname 'Είναι το όνομα της παραγόμενης τάξης,' access_specifier 'Είναι ο τρόπος πρόσβασης, δηλαδή δημόσιος, προστατευμένος ή ιδιωτικός στον οποίο η παράγωγη κλάση πρέπει να κληρονομήσει την βασική κλάση και' deriv_classname 'Είναι το όνομα της βασικής κλάσης από την οποία κληρονομεί η παράγωγη κλάση.
Τρόποι κληρονομικότητας
Το 'access_specifier' που εμφανίζεται στην παραπάνω δήλωση κληρονομιάς, μπορεί να έχει τις τιμές του όπως φαίνεται παρακάτω.
Ανάλογα με το access_specifier που καθορίζεται όταν κληρονομούμε την τάξη, έχουμε διάφορους τρόπους κληρονομιάς όπως αναφέρονται παρακάτω.
Δημόσια κληρονομιά
Γενική σύνταξη
class sub_class : public parent_class
Όταν ορίζεται ο προσδιοριστής δημόσιας πρόσβασης, τα δημόσια μέλη της κατηγορίας βάσης κληρονομούνται ως δημόσια ενώ προστατεύονται τα προστατευμένα μέλη. Τα ιδιωτικά μέλη παραμένουν ιδιωτικά. Αυτός είναι ο πιο δημοφιλής τρόπος κληρονομιάς.
Ιδιωτική κληρονομιά
Γενική σύνταξη
class sub_class : parent_class
Η ιδιωτική κληρονομιά δεν κληρονομεί τίποτα. Όταν χρησιμοποιείται προσδιοριστής ιδιωτικής πρόσβασης, δημόσια και προστατευόμενα μέλη της βασικής τάξης γίνονται επίσης ιδιωτικά.
Προστατευόμενη κληρονομικότητα
Γενική σύνταξη
class sub_class:protected parent_class
Όταν χρησιμοποιείται ο προσδιοριστής προστατευμένης πρόσβασης, τα δημόσια και προστατευόμενα μέλη της βασικής κατηγορίας γίνονται προστατευμένα μέλη στην παράγωγη κλάση.
Σημειώστε ότι όταν χρησιμοποιούμε προσδιοριστή ιδιωτικής πρόσβασης για την κατηγορία βάσης, κανένα από τα μέλη της κατηγορίας βάσης δεν κληρονομείται. Όλοι γίνονται ιδιωτικοί στην παράγωγη τάξη.
Παρακάτω δίνεται η τυποποιημένη αναπαράσταση όλων των τρόπων πρόσβασης και η ερμηνεία τους για κληρονομιά.
Παράγωγη κλάση -> Βασική τάξη | Ιδιωτικός | Δημόσιο | Προστατευμένο |
---|---|---|---|
Ιδιωτικός | Δεν κληρονομείται | Δεν κληρονομείται | Δεν κληρονομείται |
Δημόσιο | Ιδιωτικός | Δημόσιο | Προστατευμένο |
Προστατευμένο | Ιδιωτικός | Προστατευμένο | Προστατευμένο |
Διάταξη Κατασκευαστών / Καταστροφέων Κληρονομικότητας
Όταν τα μαθήματα κληρονομούνται, οι κατασκευαστές καλούνται με την ίδια σειρά με τις κληρονομικές τάξεις. Εάν έχουμε μια κλάση βάσης και μία παράγωγη κλάση που κληρονομεί αυτήν την κλάση βάσης, τότε ο κατασκευαστής βασικής κλάσης (είτε προεπιλεγμένος είτε παραμετροποιημένος) θα καλείται πρώτα ακολουθούμενος από τον κατασκευαστή της παραγόμενης κλάσης.
Το ακόλουθο πρόγραμμα δείχνει τη σειρά των κατασκευαστών στην κληρονομιά. Έχουμε μια βασική κατηγορία «Base» που έχει έναν προεπιλεγμένο κατασκευαστή και έναν παραμετροποιημένο κατασκευαστή. Παράγουμε μια κλάση από αυτό που ονομάζεται 'Derived' η οποία έχει επίσης μια προεπιλεγμένη και μια άλλη παραμετροποιημένη κατασκευή.
Η έξοδος αυτού του προγράμματος δείχνει τη σειρά με την οποία καλούνται οι κατασκευαστές.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout Παραγωγή:
Προεπιλεγμένος κατασκευαστής βασικής κλάσης
Προεπιλεγμένος κατασκευαστής βασικής κλάσης
Παράγωγος προεπιλεγμένος κατασκευαστής κλάσης
Παραμετροποιημένος κατασκευαστής κατηγορίας βάσης
Παράγωγο κατασκευαστή παράγωγης κλάσης
Βλέπουμε ότι μετά τη δημιουργία του αντικειμένου βασικής κλάσης δημιουργούμε ένα αντικείμενο κλάσης που έχει παραχθεί με έναν προεπιλεγμένο κατασκευαστή. Όταν δημιουργείται αυτό το αντικείμενο, καλείται πρώτα ο προεπιλεγμένος κατασκευαστής κλάσης βάσης και στη συνέχεια εκτελείται ο κατασκευαστής κλάσης.
Ομοίως, όταν το παραγόμενο αντικείμενο κλάσης δημιουργείται χρησιμοποιώντας τον παραμετροποιημένο κατασκευαστή, ο παραμετροποιημένος κατασκευαστής κλάσης βάσης καλείται πρώτα και στη συνέχεια καλείται ο παράγωγος κλάσης παραγόμενου.
Σημειώστε ότι εάν δεν υπήρχε παραμετροποιημένος κατασκευαστής στην βασική κλάση, τότε ο προεπιλεγμένος κατασκευαστής θα είχε κληθεί ακόμη και για την κατασκευή του παραμετροποιημένου παραγόμενου αντικειμένου κλάσης.
Αλλά παραμένει το ερώτημα γιατί καλείται ο κατασκευαστής βασικής κλάσης κατά την κατασκευή των παραγόμενων αντικειμένων κλάσης;
Γνωρίζουμε ότι ένας κατασκευαστής χρησιμοποιείται για τη δημιουργία αντικειμένων της τάξης και επίσης για την προετοιμασία των μελών της τάξης. Όταν δημιουργείται το παράγωγο αντικείμενο κλάσης, ο κατασκευαστής του ελέγχει μόνο τα παράγωγα μέλη κλάσης.
Ωστόσο, η παράγωγη τάξη κληρονομεί επίσης τα μέλη της βασικής τάξης. Εάν καλούταν μόνο ο κατασκευαστής της παραγόμενης τάξης, τότε τα μέλη της βασικής τάξης που κληρονόμησαν από την παράγωγη τάξη δεν θα αρχικοποιούνται σωστά.
Ως αποτέλεσμα, ολόκληρο το αντικείμενο δεν θα δημιουργηθεί αποτελεσματικά. Αυτός είναι ο λόγος για τον οποίο όλοι οι κατασκευαστές βασικής κλάσης καλούνται πρώτοι όταν δημιουργείται ένα παράγωγο αντικείμενο κλάσης.
Τύποι κληρονομικότητας
Ανάλογα με τον τρόπο με τον οποίο προέρχεται η τάξη ή πόσες βασικές τάξεις κληρονομεί μια τάξη, έχουμε τους ακόλουθους τύπους κληρονομιάς όπως απεικονίζονται στο παρακάτω σχήμα.

Θα εξερευνήσουμε κάθε έναν από αυτούς τους τύπους στο επόμενο σεμινάριό μας σχετικά με τους «Τύπους Κληρονομικότητας».
Πρότυπο κληρονομικότητας
Όταν η εφαρμογή μας περιλαμβάνει πρότυπα, τότε πρέπει να κληρονομήσουμε ή να προέλθουμε από κλάσεις προτύπων και χρησιμοποιούμε εκεί το πρότυπο κληρονομιάς.
πώς να αφαιρέσετε στοιχεία από έναν πίνακα java
Ας μεταβούμε απευθείας σε ένα παράδειγμα προγραμματισμού για να κατανοήσουμε καλύτερα την κληρονομιά χρησιμοποιώντας πρότυπα.
#include using namespace std; //template inhertance templateclass basecls_Template { public: T value; basecls_Template(T value) { this->value = value; } void displayVal() { cout << value << endl; } }; //derived class inherits basecls_Template class derivedcls_Child : public basecls_Template { public: derivedcls_Child(/* no parameters */): basecls_Template( 0 ){ // default char is NULL; } derivedcls_Child(char c): basecls_Template( c ) { ; } void displayVal_drvd() { displayVal(); } }; int main() { basecls_Template obj( 100 ); derivedcls_Child obj1( 'A' ); cout<<'basecls_Template obj = '; obj.displayVal(); // should print '100' cout< Παραγωγή:
basecls_Template obj = 100
derivcls_Child obj1 (κληρονομείται από basecls_Template = A
Στο παραπάνω πρόγραμμα, έχουμε ένα πρότυπο που ονομάζεται basecls_Template το οποίο καθορίζει το πρότυπο κλάσης για την βασική κλάση. Στη συνέχεια, ορίζουμε μια κλάση derivedcls_Child που θέλουμε να αντλήσουμε από μια κλάση προτύπου.
Αλλά σημειώστε ότι η κλάση basecls_Template είναι μόνο ένας τύπος και όχι μια κλάση. Ως εκ τούτου, δεν μπορούμε να αντλήσουμε την κλάση derivedcls_Child από αυτό το πρότυπο.
Επομένως, εάν δηλώσουμε την παιδική τάξη ως:
class derivedcls_Child : public basecls_Template
Αυτό θα οδηγήσει σε σφάλμα. Ο λόγος που το basecls_Template είναι τύπος δεδομένων και όχι κλάση. Έτσι, για να κληρονομήσουμε τα μέλη του basecls_Template, πρέπει πρώτα να το δημιουργήσουμε προτού το αντλήσουμε.
Επομένως, η παραπάνω δήλωση, Κατηγορία που προέρχεταιcls_Child: public basecls_Template δουλεύει μια χαρά.
Σε αυτήν τη δήλωση, έχουμε δημιουργήσει το πρότυπο basecls_Template σε ένα πρότυπο κλάσης χαρακτήρων. Μόλις χρησιμοποιήσουμε αυτήν την instantiated class class, τότε τα άλλα πράγματα που ακολουθούν όπως η δημιουργία και η χρήση αντικειμένων συμπίπτουν με τη συνήθη εργασία κληρονομιάς.
Σύνθεση
Μέχρι στιγμής έχουμε δει τα πάντα για τις σχέσεις κληρονομιάς. Η κληρονομικότητα απεικονίζει βασικά το είδος των σχέσεων όπου η σχέση δείχνει ένα μέρος. Για παράδειγμα, ένα φίδι είναι ένα είδος ερπετού. Μπορούμε επίσης να πούμε ότι το Reptile είναι μέρος της κατηγορίας Animal.
Συμπερασματικά, η κληρονομιά δείχνει 'ΕΙΝΑΙ ΕΝΑ' είδος σχέσεων όπου μπορούμε να πούμε ότι η παράγωγη τάξη είναι μέρος της βασικής τάξης.
Μπορούμε επίσης να αντιπροσωπεύσουμε τις σχέσεις στο σύνολό της. Για παράδειγμα, αν λέμε ότι η τάξη μισθών είναι μέρος της τάξης υπαλλήλων, τότε δεν την εκπροσωπούμε σωστά. Γνωρίζουμε ότι οι εργαζόμενοι έχουν μισθό. Έτσι, είναι πιο βολικό να πούμε «Ο υπάλληλος έχει μισθό».
Παρομοίως, αν πάρουμε την κατηγορία Vehicles ως παράδειγμα, μπορούμε να πούμε ότι το Vehicle έχει κινητήρα ή το Vehicle έχει πλαίσιο. Έτσι απεικονίζονται όλες αυτές οι σχέσεις 'ΕΧΕΙ ΕΝΑ' σχέσεις που αντιπροσωπεύουν ένα ολόκληρο αντικείμενο που περιέχεται σε μια άλλη τάξη. Αυτό ορίζεται ως Σύνθεση .
Οι σχέσεις που απεικονίζονται από τη σύνθεση εξαρτώνται η μία από την άλλη. Για παράδειγμα, ένα πλαίσιο δεν μπορεί να υπάρξει χωρίς όχημα. Ομοίως, ο Μισθός δεν μπορεί να υπάρχει χωρίς Υπάλληλο.
Μπορούμε να αναπαραστήσουμε τη σύνθεση διαγραμματικά όπως φαίνεται παρακάτω:

Η σύνθεση ονομάζεται επίσης περιορισμός. Στην παραπάνω αναπαράσταση, έχουμε δείξει μια τάξη γονέα. Σε αντίθεση με την κληρονομιά, συμπεριλαμβάνουμε ένα αντικείμενο παιδικής τάξης εντός της γονικής τάξης. Πρόκειται για περιορισμό ή σύνθεση.
καλύτερο λογισμικό για τη λήψη βίντεο στο YouTube
Ας πάρουμε ένα παράδειγμα προγραμματισμού για να το κατανοήσουμε αυτό.
#include using namespace std; //Composition example //Child class - address class Address { public: string houseNo, building, street, city, state; //Initialise the address object Address(string houseNo,string building,string street, string city, string state) { this->houseNo = houseNo; this->building = building; this->street = street; this->city = city; this->state = state; } }; //Parent class - Employee class Employee { private: Address* address; //composition->Employee has an address public: int empId; string empName; Employee(int empId, string empName, Address* address) { this->empId = empId; this->empName = empName; this->address = address; } void display() { cout< Παραγωγή:
10001 Ved
A-101 Silver Springs Aundh Pune Maharashtra
Σε αυτό το παράδειγμα, έχουμε μια γονική τάξη Υπάλληλος και μια θυγατρική τάξη Διεύθυνση. Μέσα στη μητρική κλάση Υπάλληλος, έχουμε δηλώσει έναν δείκτη στην κατηγορία Διεύθυνση και επίσης αρχικοποιούμε αυτό το αντικείμενο στον Κατασκευαστή εργαζομένων. Έτσι, απεικονίζουμε τη σχέση που ο υπάλληλος έχει μια διεύθυνση που είναι σύνθεση.
Πώς πρέπει να αποφασίσουμε μεταξύ της σύνθεσης και της κληρονομικότητας;
Η σύνθεση και η κληρονομιά απεικονίζουν και τις δύο σχέσεις μεταξύ τάξεων. Ενώ η κληρονομιά απεικονίζει τη σχέση «IS-A», η σύνθεση απεικονίζει τη σχέση «HAS-A».
Τώρα το ερώτημα είναι ότι πότε πρέπει να χρησιμοποιήσουμε την κληρονομιά και πότε πρέπει να χρησιμοποιήσουμε τη σύνθεση; Στην πραγματικότητα, δεν μπορούμε να αποφασίσουμε για τις ακριβείς καταστάσεις όπως πότε πρέπει να χρησιμοποιήσουμε καμία από αυτές. Αυτό συμβαίνει επειδή ο καθένας έχει τα δικά του πλεονεκτήματα και μειονεκτήματα.
Και οι δύο προωθούν την επαναχρησιμοποίηση κώδικα. Η κληρονομικότητα μπορεί να κάνει τον κώδικα ογκώδες καθώς οι λύσεις γίνονται πολύπλοκες αλλά ταυτόχρονα, μας επιτρέπει επίσης να επεκτείνουμε τον υπάρχοντα κώδικα. Έτσι, πρέπει να χρησιμοποιήσουμε την κληρονομιά όταν η απαίτησή μας είναι να τροποποιήσουμε και να χρησιμοποιήσουμε τις ιδιότητες και τη μέθοδο μιας άλλης κλάσης μέσα στη νέα τάξη.
Με άλλα λόγια, όταν θέλουμε να προσθέσουμε περισσότερες ιδιότητες και να επεκτείνουμε την υπάρχουσα τάξη. Από την άλλη πλευρά, όταν δεν θέλουμε να τροποποιήσουμε τις ιδιότητες και τη συμπεριφορά μιας άλλης τάξης, αλλά απλώς τη χρησιμοποιούμε μέσα στην τάξη, πηγαίνουμε για σύνθεση.
Έτσι, η καλύτερη απόφαση είναι το αν θα χρησιμοποιηθεί η σύνθεση ή η κληρονομιά θα ληφθεί σταθμίζοντας τα πλεονεκτήματα και τα μειονεκτήματα και των δύο τεχνικών για τη συγκεκριμένη κατάσταση.
= >> Διαβάστε επίσης Σύνθεση σε Java
συμπέρασμα
Έτσι, φτάσαμε στο τέλος του θέματος μας σχετικά με την κληρονομιά. Έχουμε δει διάφορους τρόπους κληρονομιάς. Έχουμε επίσης δει τα είδη κληρονομιάς, τα οποία θα διερευνήσουμε στο επόμενο σεμινάριό μας. Μάθαμε για τη σειρά των κατασκευαστών που εκτελούνται σε περίπτωση κληρονομιάς.
Μελετήσαμε επίσης για πρότυπα και κληρονομιά. Πρέπει να δημιουργήσουμε ένα πρότυπο για να μπορέσουμε να το χρησιμοποιήσουμε σε κληρονομικότητα, καθώς το ίδιο το πρότυπο είναι τύπος δεδομένων και δεν μπορούμε να κληρονομήσουμε από έναν τύπο δεδομένων.
Η σύνθεση είναι ένας άλλος τύπος ταξικής σχέσης και πρέπει πρώτα να γνωρίζουμε την ακριβή κατάσταση και έπειτα μόνο μπορούμε να αποφασίσουμε αν θα χρησιμοποιήσουμε τη σύνθεση ή την κληρονομιά.
Στο επερχόμενο σεμινάριό μας, θα δούμε περισσότερα για τους τύπους κληρονομιάς.
=> Παρακολουθήστε την απλή σειρά εκπαίδευσης C ++ εδώ.
Συνιστώμενη ανάγνωση
- Τύποι κληρονομικότητας σε C ++
- Πολυμορφισμός χρόνου εκτέλεσης σε C ++
- Λειτουργίες φίλων στο C ++
- Χρήση του Selenium Select Class για το χειρισμό των αναπτυσσόμενων στοιχείων σε μια ιστοσελίδα - Selenium Tutorial # 13
- Μαθήματα και αντικείμενα σε C ++
- Στατικό σε C ++
- Tutorial Unix Pipes: Pipes in Unix Programming
- Java Interface και Abstract Class Tutorial με παραδείγματα