This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Last revision Both sides next revision | ||
|
java:inheritance [2016/02/12 15:45] gthanos |
java:inheritance [2021/04/02 14:19] gthanos |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Κληρονομικότητα ====== | ====== Κληρονομικότητα ====== | ||
| - | Βασικό χαρακτηριστικό του αντικειμενοστραφούς προγραμματισμού είναι η δυνατότητα να παράγουμε νέες κλάσεις με βάση υφιστάμενες κλάσεις, εξειδικεύοντας και επεκτείνοντας τα χαρακτηριστικά των υφιστάμενων. Η διαδικασία επέκτασης των υφιστάμενων κλάσεων σε νέες ειδικότερες κλάσεις ονομάζεται κληρονομικότητα. | + | Βασικό χαρακτηριστικό του αντικειμενοστραφούς προγραμματισμού είναι η δυνατότητα να παράγουμε νέες κλάσεις με βάση υφιστάμενες, |
| Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (// | Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (// | ||
| - | {{ :java:super_sub_class.jpg | }} | + | {{ :java:inheritance-1.png | }} |
| - | Όπως φαίνεται και στο παραπάνω σχήμα μία κλάση (// | + | Όπως φαίνεται και στο παραπάνω σχήμα μία κλάση (// |
| - | <code java Bicycle.java> | + | <code java BasicRectangle.java> |
| - | public class Bicycle | + | public class BasicRectangle |
| - | + | ||
| - | private int cadence; | + | |
| - | private int gear; | + | |
| - | private int speed; | + | |
| - | + | ||
| - | public Bicycle(int startCadence, | + | |
| - | gear = startGear; | + | |
| - | cadence = startCadence; | + | |
| - | speed = startSpeed; | + | |
| - | } | + | |
| | | ||
| - | public | + | |
| - | | + | int height; |
| - | } | + | |
| + | public BasicRectangle(int initWidth, int initHeight) { | ||
| + | width = initWidth; | ||
| + | | ||
| + | } | ||
| + | |||
| + | public void setWidth(int newWidth ) { | ||
| + | width = newWidth; | ||
| + | | ||
| | | ||
| - | | + | public void setHeight(int newHeight ) { |
| - | return | + | height = newHeight; |
| - | } | + | } |
| + | |||
| + | | ||
| + | return | ||
| + | } | ||
| | | ||
| - | | + | |
| - | return | + | return |
| - | } | + | } |
| + | |||
| + | int area() { | ||
| + | | ||
| + | | ||
| + | |||
| + | public String toString() { | ||
| + | return " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | | + | <code java Point.java> |
| - | | + | class Point { |
| - | } | + | int x; // x coordinate |
| - | + | int y; // y coordinate | |
| - | | + | |
| - | | + | |
| - | } | + | |
| - | + | | |
| - | | + | |
| - | speed -= decrement; | + | |
| - | } | + | int getX() { |
| - | + | | |
| - | public | + | } |
| - | | + | |
| - | } | + | |
| - | | + | |
| + | } | ||
| + | |||
| + | int getY() { | ||
| + | | ||
| + | } | ||
| + | |||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | public | ||
| + | | ||
| + | } | ||
| } | } | ||
| </ | </ | ||
| - | <code java MountainBike.java> | + | <code java Rectangle.java> |
| - | public class MountainBike | + | public class Rectangle |
| - | + | ||
| - | | + | Point origin; |
| - | + | ||
| - | | + | public |
| - | // one constructor | + | super(initWidth, initHeight); |
| - | | + | |
| - | int startSpeed, int startGear) { | + | } |
| - | super(startCadence, startSpeed, startGear); | + | |
| - | | + | public |
| - | } | + | |
| - | + | | |
| - | // the MountainBike subclass has | + | |
| - | // one method | + | |
| - | | + | |
| - | | + | |
| - | } | + | |
| | | ||
| - | | + | |
| - | return | + | |
| - | } | + | } |
| + | |||
| + | public Point getOrigin() { | ||
| + | | ||
| + | } | ||
| + | |||
| + | // Move rectangle origin by dx,dy | ||
| + | public void moveOrigin(int dx, int dy) { | ||
| + | | ||
| + | origin.setY( origin.getY() + dy ); | ||
| + | } | ||
| + | |||
| + | public String toString() { | ||
| + | String str = origin.toString() + " "; | ||
| + | str = str + super.toString(); | ||
| + | return str; | ||
| + | | ||
| } | } | ||
| </ | </ | ||
| + | <WRAP tip 80% center round> | ||
| + | |||
| + | === Παρατηρήσεις === | ||
| + | |||
| + | * Η κλάση // | ||
| + | * Βασικό χαρακτηριστικό της κληρονομικότητας είναι ότι η κληρονομούμενη κλάση έχει όλα τα χαρακτηριστικά της γονικής κλάσης. Υπό αυτή την έννοια, | ||
| + | * Παρατηρήστε τη δεσμευμένη λέξη //super// ως πρώτη εντολή του κάθε κατασκευαστή. Μέσω της κλήσης //super// καλείται ο κατασκευαστής της γονικής κλάσης. | ||
| + | </ | ||
| ===== Προσβασιμότητα των κληρονομούμενων πεδίων ===== | ===== Προσβασιμότητα των κληρονομούμενων πεδίων ===== | ||
| Μία κλάση η οποία κληρονομεί μία άλλη κλάση έχει πρόσβαση στα μέλη (πεδία και μεθόδους) της κλάσης αυτής ως εξής: | Μία κλάση η οποία κληρονομεί μία άλλη κλάση έχει πρόσβαση στα μέλη (πεδία και μεθόδους) της κλάσης αυτής ως εξής: | ||
| - | * Έχει πρόσβαση στα //public// και // | + | * Έχει πρόσβαση στα //**public**// και //**protected**// μέλη της γονικής κλάσης |
| - | * Έχει πρόσβαση στα //package private// μέλη (δηλ. τα μέλη χωρίς προσδιοριστή πρόσβασης) μόνο αν βρίσκεται στο ίδιο πακέτο με την γονική κλάση. | + | * Έχει πρόσβαση στα //**package private**// μέλη (δηλ. τα μέλη χωρίς προσδιοριστή πρόσβασης) μόνο αν βρίσκεται στο ίδιο πακέτο με την γονική κλάση. |
| - | * Δεν έχει πρόσβαση στα //private// μέλη της κλάσης. | + | * Δεν έχει πρόσβαση στα //**private**// μέλη της κλάσης. |
| - | Αν υπάρχουν //public// μέθοδοι οι οποίες επιτρέπουν την πρόσβαση σε //private// πεδία, τότε αυτές μπορούν να χρησιμοποιηθούν για τον ορισμό ή για την λήψη της τιμής τους. | + | Αν υπάρχουν //**public**// μέθοδοι οι οποίες επιτρέπουν την πρόσβαση σε //**private**// πεδία, τότε αυτές μπορούν να χρησιμοποιηθούν για τον ορισμό ή για την λήψη της τιμής τους. |
| ===== Τι μπορούμε να κάνουμε σε μία υποκλάση... ===== | ===== Τι μπορούμε να κάνουμε σε μία υποκλάση... ===== | ||
| Line 92: | Line 137: | ||
| * Να χρησιμοποιήσουμε τα πεδία της γονικής κλάσης στα οποία έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | * Να χρησιμοποιήσουμε τα πεδία της γονικής κλάσης στα οποία έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | ||
| * Να ορίσουμε νέα πεδία. | * Να ορίσουμε νέα πεδία. | ||
| - | * Να ορίσουμε νέα πεδία που να έχουν ίδιο όνομα με πεδία της γονικής κλάσης. Σε αυτή την περίπτωση " | ||
| * Να χρησιμοποιήσουμε τις μεθόδους της γονικής κλάσης στις οποίες έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | * Να χρησιμοποιήσουμε τις μεθόδους της γονικής κλάσης στις οποίες έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | ||
| * Μπορούμε να γράψουμε νέες στατικές ή μη στατικές μεθόδους για τη υποκλάση. | * Μπορούμε να γράψουμε νέες στατικές ή μη στατικές μεθόδους για τη υποκλάση. | ||
| Line 99: | Line 143: | ||
| * Μπορούμε να γράψουμε κατασκευαστές της υποκλάσης που χρησιμοποιούν κατασκευαστές της γονικής κλάσης. | * Μπορούμε να γράψουμε κατασκευαστές της υποκλάσης που χρησιμοποιούν κατασκευαστές της γονικής κλάσης. | ||
| - | ===== Implicit και Explicit Casting of Objects ===== | + | ===== ΔΕΝ |
| - | + | * Να ορίσουμε νέα πεδία που | |
| - | Σε συνέχεια του προηγούμενου παραδείγματος κληρονομικότητας μπορούμε | + | |
| - | + | ||
| - | <code java> | + | |
| - | MountainBike myBike = new MountainBike(); | + | |
| - | </ | + | |
| - | + | ||
| - | Από την παραπάνω δήλωση η μεταβλητή '' | + | |
| - | + | ||
| - | <code java> | + | |
| - | Bicycle myBicycle | + | |
| - | // | + | |
| - | Βicycle yourBicycle | + | |
| - | </ | + | |
| - | + | ||
| - | Την παραπάνω ανάθεση την ονομάζουμε | + | |
| - | + | ||
| - | Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα | + | |
| - | + | ||
| - | <code java> | + | |
| - | Bycycle myBicycle = new Bicycle(); | + | |
| - | MountainBike myBike = myBicycle; | + | |
| - | </ | + | |
| - | + | ||
| - | Σε αυτή την περίπτωση | + | |
| - | + | ||
| - | <code java> | + | |
| - | Bycycle myBicycle = new Bicycle(); | + | |
| - | MountainBike myBike = (MountainBike) myBicycle; | + | |
| - | </ | + | |
| - | + | ||
| - | Εδώ ενημερώνουμε τον compiler ότι η μεταβλητή '' | + | |
| - | + | ||
| - | Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα, | + | |
| - | + | ||
| - | <code java> | + | |
| - | Bycycle myBicycle = new Bicycle(); | + | |
| - | MountainBike myBike; | + | |
| - | if (myBicycle instanceof MountainBike) { | + | |
| - | myBike = (MountainBike)myBicycle; | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | ===== Final Κλάσεις και Μέθοδοι ===== | + | |
| - | + | ||
| - | Μπορείτε να δηλώσετε μία ή περισσότερες μεθόδους μία κλάσης ως //final//. Δηλώνοντας μία μέθοδο ως final η μέθοδος αυτή δεν μπορεί να επαναοριστεί σε μία υποκλάση της κλάσης αυτής. Ο συχνότερος λόγος για να δηλώσετε μία | + | |
| - | + | ||
| - | <code java> | + | |
| - | class ChessAlgorithm { | + | |
| - | enum ChessPlayer { WHITE, BLACK } | + | |
| - | ... | + | |
| - | final ChessPlayer getFirstPlayer() { | + | |
| - | return ChessPlayer.WHITE; | + | |
| - | } | + | |
| - | ... | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Γενικότερα, μέθοδοι που καλούνται από τους κατασκευαστές της κλάσης __θα πρέπει__ να ορίζονται | + | |
| - | + | ||
| - | Τέλος, | + | |
| - | |Προηγούμενο: | + | |Προηγούμενο: |