java:inheritance

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
java:inheritance [2016/02/12 15:47]
gthanos [Προσβασιμότητα των κληρονομούμενων πεδίων]
java:inheritance [2016/03/31 08:25] (current)
doufexi [Τι μπορούμε να κάνουμε σε μία υποκλάση...]
Line 1: Line 1:
 ====== Κληρονομικότητα ====== ====== Κληρονομικότητα ======
  
-Βασικό χαρακτηριστικό του αντικειμενοστραφούς προγραμματισμού είναι η δυνατότητα να παράγουμε νέες κλάσεις με βάση υφιστάμενες κλάσεις,​ εξειδικεύοντας και επεκτείνοντας τα χαρακτηριστικά των υφιστάμενων. Η διαδικασία επέκτασης των υφιστάμενων κλάσεων σε νέες ειδικότερες κλάσεις ονομάζεται κληρονομικότητα.+Βασικό χαρακτηριστικό του αντικειμενοστραφούς προγραμματισμού είναι η δυνατότητα να παράγουμε νέες κλάσεις με βάση υφιστάμενες κλάσεις,​ εξειδικεύοντας και επεκτείνοντας τα χαρακτηριστικά τους. Η διαδικασία επέκτασης των υφιστάμενων κλάσεων σε νέες ειδικότερες κλάσεις ονομάζεται κληρονομικότητα.
  
 Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (//​subclass//​) της γονικής κλάσης από την οποία κληρονομεί. Αντίστοιχα,​ η γονική κλάση ονομάζεται υπερκλάση (//​superclass//​) της κληρονομούμενης κλάσης. Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (//​subclass//​) της γονικής κλάσης από την οποία κληρονομεί. Αντίστοιχα,​ η γονική κλάση ονομάζεται υπερκλάση (//​superclass//​) της κληρονομούμενης κλάσης.
Line 99: Line 99:
   * Μπορούμε να γράψουμε κατασκευαστές της υποκλάσης που χρησιμοποιούν κατασκευαστές της γονικής κλάσης.   * Μπορούμε να γράψουμε κατασκευαστές της υποκλάσης που χρησιμοποιούν κατασκευαστές της γονικής κλάσης.
  
-===== Implicit ​και ​Explicit Casting of Objects =====+| Προηγούμενο : [[  :​java:​access_modifiers | Περιοριστές πρόσβασης ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο:​ [[ :​java:​type_casting | Ρητές (explicit) ​και ​άρρητες (implicit) μετατροπές τύπων ]]  |
  
-Σε συνέχεια του προηγούμενου παραδείγματος κληρονομικότητας μπορούμε να γράψουμε 
- 
-<code java> 
-MountainBike myBike = new MountainBike();​ 
-</​code>​ 
- 
-Από την παραπάνω δήλωση η μεταβλητή ''​myBike''​ είναι τύπου ''​MountainBike''​. Επειδή όμως ο τύπος ''​MountainBike''​ κληρονομεί από την μεταβλητή ''​Bicycle''​ η συγκεκριμένη μεταβλητή είναι και τύπου Bicycle. Επομένως θα μπορούσαμε να γράψουμε 
- 
-<code java> 
-Bicycle myBicycle = myBike; 
-   //ή 
-Βicycle yourBicycle = new MountainBike();​ 
-</​code>​ 
- 
-Την παραπάνω ανάθεση την ονομάζουμε //Implicit Casting// διότι αναθέτουμε μία μεταβλητή ενός τύπου δεδομένων (''​myBike''​) σε μία μεταβλητή γονικού τύπου δεδομένων (''​myBicycle''​),​ χωρίς type casting. 
- 
-Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα 
- 
-<code java> 
-Bycycle myBicycle = new Bicycle(); 
-MountainBike myBike = myBicycle; 
-</​code>​ 
- 
-Σε αυτή την περίπτωση ο compiler διαμαρτύρεται,​ διότι η μεταβλητή ''​myBicycle''​ είναι τύπου ''​Bicycle''​ και δεν είναι απαραίτητο ότι είναι και τύπου ''​MountainBike''​. Αν θέλουμε να ξεπεράσουμε το παραπάνω πρόβλημα θα πρέπει να γράψουμε το εξής: 
- 
-<code java> 
-Bycycle myBicycle = new Bicycle(); 
-MountainBike myBike = (MountainBike) myBicycle; 
-</​code>​ 
- 
-Εδώ ενημερώνουμε τον compiler ότι η μεταβλητή ''​myBicycle''​ είναι και τύπου ''​MountainBike'',​ λαμβάνοντας ο προγραμματιστής την ευθύνη ότι κάτι τέτοιο ισχύει. Εάν δεν ισχύει κάτι τέτοιο κατά την εκτέλεση του προγράμματος θα παραχθεί μία εξαίρεση (exception)*. Θα δούμε πιο κάτω τι είναι και πως διαχειριζόμαστε τις εξαιρέσεις. 
- 
-Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα,​ χωρίς να παραχθεί εξαίρεση είναι ο εξής: 
- 
-<code java> 
-Bycycle myBicycle = new Bicycle(); 
-MountainBike myBike; 
-if (myBicycle instanceof MountainBike) { 
-    myBike = (MountainBike)myBicycle;​ 
-} 
-</​code>​ 
- 
-===== Final Κλάσεις και Μέθοδοι ===== 
- 
-Μπορείτε να δηλώσετε μία ή περισσότερες μεθόδους μία κλάσης ως //final//. Δηλώνοντας μία μέθοδο ως final η μέθοδος αυτή δεν μπορεί να επαναοριστεί σε μία υποκλάση της κλάσης αυτής. Ο συχνότερος λόγος για να δηλώσετε μία μέθοδο ως //final// είναι αν η υλοποίηση της μεθόδου δεν πρέπει να αλλάξει. Ένα παράδειγμα είναι το παρακάτω:​ 
- 
-<code java> 
-class ChessAlgorithm { 
-    enum ChessPlayer { WHITE, BLACK } 
-    ... 
-    final ChessPlayer getFirstPlayer() { 
-        return ChessPlayer.WHITE;​ 
-    } 
-    ... 
-} 
-</​code>​ 
- 
-Γενικότερα,​ μέθοδοι που καλούνται από τους κατασκευαστές της κλάσης __θα πρέπει__ να ορίζονται ως //final// καθώς αν αλλάζουν την υλοποίηση τους σε υποκλάσεις μπορούν να δημιουργηθούν προβλήματα ως προς την ορθή αρχικοποίηση των μεταβλητών της κλάσης. 
- 
-Τέλος, μπορείτε να προσδιορίσετε μία κλάση ως //final//, όταν θέλετε να δηλώσετε ότι η συγκεκριμένη κλάση δεν πρέπει να έχει υποκλάσεις. Ένα παράδειγμα τέτοια κλάσης είναι η κλάση [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​String.html | String]] της standard βιβλιοθήκης της Java. 
- 
-|Προηγούμενο:​ [[ :​java:​interfaces | Διεπαφές ]] | Επόμενο:​ [[ :​java:​multiple_inheritance | Κληρονομικότητα πολλαπλών γονικών κλάσεων ]]| 
  
java/inheritance.1455292058.txt.gz · Last modified: 2016/02/26 11:15 (external edit)