User Tools

Site Tools


cpp:inheritance

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
cpp:inheritance [2020/04/14 16:41] gthanoscpp:inheritance [2022/05/13 07:01] (current) – [Κληρονομικότητα] gthanos
Line 3: Line 3:
 Οι κλάσεις στη C++ μπορούν να επεκταθούν μέσω της κληρονομικότητας, δημιουργώντας νέες κλάσεις που διατηρούν τα χαρακτηριστικά των προγόνων τους. Η κληρονομικότητα προϋποθέτει ότι υπάρχει η βασική κλάση (πρόγονος) από την οποία προκύπτουν μία ή περισσότερες κλάσεις (απόγονοι). Οι απόγονοι διατηρούν τα χαρακτηριστικά του προγόνου, αλλά έχουν την δυνατότητα να προσθέσουν και επιπλέον χαρακτηριστικά στη νέα κλάση. Οι κλάσεις στη C++ μπορούν να επεκταθούν μέσω της κληρονομικότητας, δημιουργώντας νέες κλάσεις που διατηρούν τα χαρακτηριστικά των προγόνων τους. Η κληρονομικότητα προϋποθέτει ότι υπάρχει η βασική κλάση (πρόγονος) από την οποία προκύπτουν μία ή περισσότερες κλάσεις (απόγονοι). Οι απόγονοι διατηρούν τα χαρακτηριστικά του προγόνου, αλλά έχουν την δυνατότητα να προσθέσουν και επιπλέον χαρακτηριστικά στη νέα κλάση.
  
-Στο παρακάτω παράδειγμα, από την κλάση //Shape// (διδιάστατο σχήμα) προκύπτει η κλάση //Rectangle// (ορθογώνιο παραλληλόγραμμο). Η κλάση //Shape// ορίζει την //private// μεταβλητή //color// που αφορά το χρώμα του τετραγώνου και το οποίο αποθηκεύεται σε μορφή [[wp>RGB]] και την //protected// μεταβλητή //borderWidth// που αφορά το πάχος του πλαισίου γύρο από το σχήμα.+Στο παρακάτω παράδειγμα, από την κλάση //Shape// (διδιάστατο σχήμα) προκύπτει η κλάση //Rectangle// (ορθογώνιο παραλληλόγραμμο). Η κλάση //Shape// ορίζει την //private// μεταβλητή //color// που αφορά το χρώμα του σχήματος, το οποίο αποθηκεύεται σε μορφή [[wp>RGB]] και την //protected// μεταβλητή //borderWidth// που αφορά το πάχος του πλαισίου γύρο από το σχήμα.
  
 <code cpp Shape.hpp> <code cpp Shape.hpp>
- 
 class Shape { class Shape {
     unsigned int color;     unsigned int color;
Line 17: Line 16:
     void setColor(unsigned char red, unsigned char blue, unsigned char green);     void setColor(unsigned char red, unsigned char blue, unsigned char green);
     unsigned int getColor();     unsigned int getColor();
-    unsigned char getBorderWidth(); 
-    void setBorderWidth(unsigned char bw); 
     unsigned int getArea();     unsigned int getArea();
 }; };
Line 25: Line 22:
 <code cpp Shape.cpp> <code cpp Shape.cpp>
 #include <iostream> #include <iostream>
-#include <string> 
 using namespace std; using namespace std;
 +
 +#include "Shape.hpp"
  
 void Shape::setColor(unsigned int c) { color = c; } void Shape::setColor(unsigned int c) { color = c; }
Line 51: Line 49:
   return 0;   return 0;
 } }
- 
-unsigned char Shape::getBorderWidth() { return borderWidth; } 
-void Shape::setBorderWidth(unsigned char bw) { borderWidth = bw; } 
- 
 </code> </code>
  
 <code cpp Rectangle.hpp> <code cpp Rectangle.hpp>
- 
 #include "Shape.hpp" #include "Shape.hpp"
  
Line 71: Line 64:
     unsigned int getHeight();     unsigned int getHeight();
     unsigned int getArea();     unsigned int getArea();
 +    
 +    unsigned char getBorderWidth();
 +    void setBorderWidth(unsigned char bw);
 }; };
- 
 </code> </code>
  
Line 78: Line 73:
 #include <iostream> #include <iostream>
 using namespace std; using namespace std;
 +
 +#include "Rectangle.hpp"
  
 Rectangle::Rectangle(unsigned int c, unsigned char bw, unsigned int w, unsigned int h) :  Rectangle::Rectangle(unsigned int c, unsigned char bw, unsigned int w, unsigned int h) : 
Line 94: Line 91:
   return Shape::getArea() + width * height;   return Shape::getArea() + width * height;
 } }
 +
 +unsigned char Rectangle::getBorderWidth() { return borderWidth; }
 +void Rectangle::setBorderWidth(unsigned char bw) { borderWidth = bw; }
 </code> </code>
  
-<code cpp ShapeUsage.cpp>+<code cpp RectangleUsage.cpp>
 #include "Rectangle.hpp" #include "Rectangle.hpp"
 +#include <iostream>
 +using namespace std;
  
 int main() { int main() {
   Rectangle rectangle(0xffffff, 2, 10, 20);   Rectangle rectangle(0xffffff, 2, 10, 20);
 +  rectangle.setBorderWidth(8);
      
   cout << "[Rectangle Properties] ";   cout << "[Rectangle Properties] ";
-  cout << " color: 0x" << hex << rectangle.getColor() << dec;+  cout << " color: 0x" << std::hex << rectangle.getColor() << dec;
   cout << " borderWidth: " << (int)rectangle.getBorderWidth();   cout << " borderWidth: " << (int)rectangle.getBorderWidth();
   cout << " area: " << rectangle.getArea() << endl;   cout << " area: " << rectangle.getArea() << endl;
Line 115: Line 118:
   - Η απόγονος κλάση μπορεί να ορίσει επιπλέον πεδία και επιπλέον μεθόδους. Η απόγονος κλάση //Rectangle// ορίζει τα επιπλέον πεδία //width, height// και τις επιπλέον μεθόδους //getWidth//, //getHeight//, //setWidth//, //setHeight//.   - Η απόγονος κλάση μπορεί να ορίσει επιπλέον πεδία και επιπλέον μεθόδους. Η απόγονος κλάση //Rectangle// ορίζει τα επιπλέον πεδία //width, height// και τις επιπλέον μεθόδους //getWidth//, //getHeight//, //setWidth//, //setHeight//.
   - Η απόγονος κλάση μπορεί να επαναορίσει μία μέθοδο η οποία είναι ήδη ορισμένη στη γονική κλάση. Η απόγονος κλάση //Rectangle// επαναορίζει τη μέθοδο //getArea//.   - Η απόγονος κλάση μπορεί να επαναορίσει μία μέθοδο η οποία είναι ήδη ορισμένη στη γονική κλάση. Η απόγονος κλάση //Rectangle// επαναορίζει τη μέθοδο //getArea//.
-  - Τα μέλη της γονικής κλάσης //Shape// που είναι δηλωμένα ως //protected// είναι προσβάσιμα από την απόγονο κλάση. Στο παραπάνω παράδειγμα η απόγονος κλάση //Rectangle// έχει πρόσβαση στο //protected// πεδίο //borderWidth// της γονικής κλάης. +  - Τα μέλη της γονικής κλάσης //Shape// που είναι δηλωμένα ως //protected// είναι προσβάσιμα από την απόγονο κλάση. Στο παραπάνω παράδειγμα η απόγονος κλάση //Rectangle// έχει πρόσβαση στο //protected// πεδίο //borderWidth// της γονικής κλάσης. 
   - Τα μέλη της γονικής κλάσης //Shape// που είναι δηλωμένα ως //private// δεν είναι προσβάσιμα από την απόγονο κλάση //Rectangle//.   - Τα μέλη της γονικής κλάσης //Shape// που είναι δηλωμένα ως //private// δεν είναι προσβάσιμα από την απόγονο κλάση //Rectangle//.
   - Όπως και στη Java, τα μέλη της γονικής κλάσης //Shape// ή της απογόνου κλάσης //Rectangle// που είναι δηλωμένα ως //public// είναι προσβάσιμα από οποιαδήποτε κλάση ή μέθοδο. Για παράδειγμα η //public// μεθόδος //getColor// της κλάσης //Shape// είναι προσβάσιμη από οποιοδήποτε κλάση ή μέθοδο (στο παράδειγμα από τη μέθοδο main).   - Όπως και στη Java, τα μέλη της γονικής κλάσης //Shape// ή της απογόνου κλάσης //Rectangle// που είναι δηλωμένα ως //public// είναι προσβάσιμα από οποιαδήποτε κλάση ή μέθοδο. Για παράδειγμα η //public// μεθόδος //getColor// της κλάσης //Shape// είναι προσβάσιμη από οποιοδήποτε κλάση ή μέθοδο (στο παράδειγμα από τη μέθοδο main).
Line 122: Line 125:
 ^                  ^  μέλη της γονικής κλάσης  ^^^ ^                  ^  μέλη της γονικής κλάσης  ^^^
 ^  προσβασιμότητα  ^  public  ^  protected  ^  private  ^ ^  προσβασιμότητα  ^  public  ^  protected  ^  private  ^
-| μέλη της ίδιας κλάσης  |  ναι  |  ναι  |  ναι +από μεθόδους της ίδιας κλάσης  |  ναι  |  ναι  |  ναι 
-| μέλη υποκλάσης  |  ναι  |  ναι  |  όχι   | +από μεθόδους μίας υποκλάσης  |  ναι  |  ναι  |  όχι   | 
-| μη μέλη της κλάσης  |  ναι  |  όχι  |  όχι  |+από μία άλλη κλάση χωρίς σχέση κληρονομικότητας  |  ναι  |  όχι  |  όχι  |
  
 +===== Κλήση μιας επανα-ορισμένης μεθόδου της γονικής κλάσης από την υποκλάση =====
  
-<WRAP center round info 80%> +Όταν η απόγονος κλάση επαναορίζει μία μέθοδο με το ίδιο //signature// (ίδιο όνομα, ίδιος αριθμός και τύπος ορισμάτων) τότε συχνά θέλουμε να καλέσουμε τη μέθοδο της γονικής κλάσης στην απόγονο κλάση προκειμένου να την επεκτείνουμε. Ο τρόπος κλήσης της γονικής μεθόδου είναι βάζοντας ως πρόθεμα στο όνομα της μεθόδου το όνομα της γονικής κλάσης. Από το παραπάνω παράδειγμα, δείτε την υλοποίηση της συνάρτησης //getArea// στην κλάση //Rectangle// η οποία χρησιμοποιεί την συνάρτηση //getArea// της γονικής κλάσης //Shape//.
-Όταν η απόγονος κλάση επαναορίζει μία μέθοδο με το ίδιο signature (ίδιο όνομα, ίδιος αριθμός και τύπος ορισμάτων) τότε συχνά θέλουμε να χρησιμοποιήσουμε τη γονική μέθοδο προκειμένου να την επεκτείνουμε. Ο τρόπος χρήσης της γονικής μεθόδου είναι βάζοντας ως πρόθεμα στη μέθοδο το όνομα της γονικής κλάσης. Από το παραπάνω παράδειγμα, δείτε την υλοποίηση της συνάρτησης //getArea// στην κλάση //Rectangle// η οποία χρησιμοποιεί την συνάρτηση //getArea// της γονικής κλάσης //Shape//.+
 <code cpp> <code cpp>
 unsigned int Rectangle::getArea() { unsigned int Rectangle::getArea() {
Line 134: Line 137:
 } }
 </code> </code>
-</WRAP> 
  
  
cpp/inheritance.1586882497.txt.gz · Last modified: 2020/04/14 15:41 (external edit)