This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
java:inheritance [2015/02/13 12:17] gthanos created |
java:inheritance [2016/03/31 08:25] doufexi [Τι μπορούμε να κάνουμε σε μία υποκλάση...] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Κληρονομικότητα ====== | ====== Κληρονομικότητα ====== | ||
- | Σε προηγούμενη παράγραφο, αναφερόμενοι στην κλάση [[:java:class:Κληρονομικότητα Κλάσης | έγινε αναφορά και στην κληρονομικότητα κλάσεων]] στην Java. | + | Βασικό χαρακτηριστικό του αντικειμενοστραφούς προγραμματισμού είναι η δυνατότητα να παράγουμε νέες κλάσεις με βάση υφιστάμενες κλάσεις, εξειδικεύοντας και επεκτείνοντας τα χαρακτηριστικά τους. Η διαδικασία επέκτασης των υφιστάμενων κλάσεων σε νέες ειδικότερες κλάσεις ονομάζεται κληρονομικότητα. |
+ | |||
+ | Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (//subclass//) της γονικής κλάσης από την οποία κληρονομεί. Αντίστοιχα, η γονική κλάση ονομάζεται υπερκλάση (//superclass//) της κληρονομούμενης κλάσης. | ||
+ | |||
+ | {{ :java:super_sub_class.jpg | }} | ||
+ | |||
+ | Όπως φαίνεται και στο παραπάνω σχήμα μία κλάση (//subclass//) μπορεί να κληρονομεί __**ΜΟΝΟ ΜΙΑ**__ άλλη κλάση. Αντίστροφα μία κλάση (//superclass//) μπορεί να κληρονομείται από πολλές διαφορετικές κλάσεις. Παρακάτω δίνουμε ένα παράδειγμα κληρονομικότητας από το site της [[https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html|Oracle]], όπου η κλάση ''MountainBike'' αποτελεί εξειδίκευση της κλάσης ''Bicycle''. | ||
+ | |||
+ | <code java Bicycle.java> | ||
+ | public class Bicycle { | ||
+ | |||
+ | private int cadence; | ||
+ | private int gear; | ||
+ | private int speed; | ||
+ | |||
+ | public Bicycle(int startCadence, int startSpeed, int startGear) { | ||
+ | gear = startGear; | ||
+ | cadence = startCadence; | ||
+ | speed = startSpeed; | ||
+ | } | ||
+ | |||
+ | public int getCadence() { | ||
+ | return cadence; | ||
+ | } | ||
+ | |||
+ | public int getGear() { | ||
+ | return gear; | ||
+ | } | ||
+ | |||
+ | public int getSpeed() { | ||
+ | return speed; | ||
+ | } | ||
+ | |||
+ | public void setCadence(int newValue) { | ||
+ | cadence = newValue; | ||
+ | } | ||
+ | |||
+ | public void setGear(int newValue) { | ||
+ | gear = newValue; | ||
+ | } | ||
+ | |||
+ | public void applyBrake(int decrement) { | ||
+ | speed -= decrement; | ||
+ | } | ||
+ | |||
+ | public void speedUp(int increment) { | ||
+ | speed += increment; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code java MountainBike.java> | ||
+ | public class MountainBike extends Bicycle { | ||
+ | |||
+ | private int seatHeight; | ||
+ | |||
+ | // the MountainBike subclass has | ||
+ | // one constructor | ||
+ | public MountainBike(int startHeight, int startCadence, | ||
+ | int startSpeed, int startGear) { | ||
+ | super(startCadence, startSpeed, startGear); | ||
+ | seatHeight = startHeight; | ||
+ | } | ||
+ | |||
+ | // the MountainBike subclass has | ||
+ | // one method | ||
+ | public void setHeight(int newValue) { | ||
+ | seatHeight = newValue; | ||
+ | } | ||
+ | |||
+ | public int getSeatHeight() { | ||
+ | return seatHeight; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Προσβασιμότητα των κληρονομούμενων πεδίων ===== | ||
+ | |||
+ | Μία κλάση η οποία κληρονομεί μία άλλη κλάση έχει πρόσβαση στα μέλη (πεδία και μεθόδους) της κλάσης αυτής ως εξής: | ||
+ | |||
+ | * Έχει πρόσβαση στα //**public**// και //**protected**// μέλη της γονικής κλάσης | ||
+ | * Έχει πρόσβαση στα //**package private**// μέλη (δηλ. τα μέλη χωρίς προσδιοριστή πρόσβασης) μόνο αν βρίσκεται στο ίδιο πακέτο με την γονική κλάση. | ||
+ | * Δεν έχει πρόσβαση στα //**private**// μέλη της κλάσης. | ||
+ | |||
+ | Αν υπάρχουν //**public**// μέθοδοι οι οποίες επιτρέπουν την πρόσβαση σε //**private**// πεδία, τότε αυτές μπορούν να χρησιμοποιηθούν για τον ορισμό ή για την λήψη της τιμής τους. | ||
+ | |||
+ | ===== Τι μπορούμε να κάνουμε σε μία υποκλάση... ===== | ||
+ | |||
+ | * Να χρησιμοποιήσουμε τα πεδία της γονικής κλάσης στα οποία έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | ||
+ | * Να ορίσουμε νέα πεδία. | ||
+ | * Να ορίσουμε νέα πεδία που να έχουν ίδιο όνομα με πεδία της γονικής κλάσης. Σε αυτή την περίπτωση "κρύβουμε" τα πεδία της γονικής κλάσης. Η συγκεκριμένη πρακτική δεν συνίσταται και παραπέμπει σε λανθασμένη σχεδίαση κώδικα. | ||
+ | * Να χρησιμοποιήσουμε τις μεθόδους της γονικής κλάσης στις οποίες έχουμε πρόσβαση (public, protected, package-private στο ίδιο package). | ||
+ | * Μπορούμε να γράψουμε νέες στατικές ή μη στατικές μεθόδους για τη υποκλάση. | ||
+ | * Μπορούμε να γράψουμε νέες μεθόδους που έχουν το ίδιο //signature// (ίδιο όνομα, ίδιο αριθμό και ίδιο τύπο ορισμάτων), ώστε να επαναορίσουμε (//override//) τις μεθόδους αυτές στην υποκλάση. Η πρακτική αυτή είναι συνήθης. | ||
+ | * Μπορούμε να γράψουμε νέες στατικές (//static//) μεθόδους που έχουν το ίδιο //signature//, ώστε να επαναορίσουμε (//override//) τις μεθόδους αυτές στην υποκλάση. Επαναορίζοντας στατικές μεθόδους, κρύβουμε τις αντίστοιχες μεθόδους της γονικής κλάσης. | ||
+ | * Μπορούμε να γράψουμε κατασκευαστές της υποκλάσης που χρησιμοποιούν κατασκευαστές της γονικής κλάσης. | ||
+ | |||
+ | | Προηγούμενο : [[ :java:access_modifiers | Περιοριστές πρόσβασης ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο: [[ :java:type_casting | Ρητές (explicit) και άρρητες (implicit) μετατροπές τύπων ]] | | ||