Both sides previous revisionPrevious revisionNext revision | Previous revision |
java:type_casting [2017/02/16 13:26] – gthanos | java:type_casting [Unknown date] (current) – external edit (Unknown date) 127.0.0.1 |
---|
| |
<code java> | <code java> |
MountainBike myBike = new MountainBike(); | Rectangle r1 = new Rectangle(100,100,5,-5); |
</code> | </code> |
| |
Από την παραπάνω δήλωση η μεταβλητή ''myBike'' είναι τύπου ''MountainBike''. Επειδή όμως ο τύπος ''MountainBike'' κληρονομεί από την μεταβλητή ''Bicycle'' **__η συγκεκριμένη μεταβλητή είναι και τύπου Bicycle__**. Επομένως, θα μπορούσαμε να γράψουμε | Από την παραπάνω δήλωση η μεταβλητή ''r1'' είναι τύπου ''Rectangle''. Επειδή όμως ο τύπος ''Rectangle'' κληρονομεί την κλάση ''BasicRectangle'' **η μεταβλητή r1 είναι και τύπου BasicRectangle**. Επομένως, θα μπορούσαμε να γράψουμε |
| |
<code java> | <code java> |
Bicycle myBicycle = myBike; | BasicRectangle r2 = r1; |
//ή | //ή ισοδύναμα |
Βicycle yourBicycle = new MountainBike(); | BasicRectangle r2 = new Rectangle(100,100,5,-5); |
</code> | </code> |
| |
Την παραπάνω ανάθεση την ονομάζουμε άρρητη μετατροπή (//implicit casting//) διότι αναθέτουμε μία μεταβλητή ενός τύπου δεδομένων (''myBike'') σε μία μεταβλητή γονικού τύπου δεδομένων (''myBicycle''), χωρίς να ορίζουμε μία μετατροπή τύπου (//type cast//). | Την παραπάνω ανάθεση την ονομάζουμε άρρητη μετατροπή (//implicit casting//) διότι αναθέτουμε ένα αντικείμενο του κληρονομούμενου τύπου δεδομένων (''r1'') σε μία μεταβλητή του γονικού τύπου (''r2''), χωρίς να ορίζουμε κάποια μετατροπή τύπου. |
| |
| Αν θέλουμε να ζωγραφίσουμε τον κώδικα του προηγούμενου παραδείγματος μπορούμε να το κάνουμε όπως στο παρακάτω σχήμα. Παρατηρήστε ότι η μεταβλητές **r1** και **r2** δείχνουν στο ίδιο αντικείμενο. Η διαφορά είναι ότι η **r2** αν και δείχνει σε ένα αντικείμενο τύπου **Rectangle**, έχει πρόσβαση μόνο στο τμήμα του αντικειμένου που είναι του τύπου **BasicRectangle**. Ο λόγος για αυτόν τον περιορισμό είναι ότι λόγω του τύπου της ο //compiler// υποθέτει ότι δείχνει σε ένα αντικείμενο τύπου **BasicRectangle** με αποτέλεσμα να μην επιτρέπει την πρόσβαση στα πεδία και τις μεθόδους που δεν ανήκουν στην κλάση **BasicRectangle**, αλλά στην υποκλάση. |
| |
| {{ :java:implicit-casting.png |}} |
| |
| === Ρητή μετατροπή === |
| |
Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα | Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα |
| |
<code java> | <code java> |
Bycycle myBicycle = new Bicycle(); | BasicRectangle r3 = new Rectangle(100,200,5,-5); |
MountainBike myBike = myBicycle; | Rectangle r4 = r3; |
</code> | </code> |
| |
Σε αυτή την περίπτωση ο compiler διαμαρτύρεται, διότι η μεταβλητή ''myBicycle'' είναι τύπου ''Bicycle'' και δεν είναι απαραίτητο ότι είναι και τύπου ''MountainBike''. Αν θέλουμε να ξεπεράσουμε το παραπάνω μήνυμα λάθους του compiler θα πρέπει να γράψουμε το εξής: | Σε αυτή την περίπτωση ο //compiler// διαμαρτύρεται, διότι η μεταβλητή ''r3'' είναι τύπου ''BasicRectangle'' και όχι τύπου ''Rectangle''. Αν θέλουμε να ξεπεράσουμε το παραπάνω μήνυμα λάθους του compiler θα πρέπει να γράψουμε το εξής: |
| |
<code java> | <code java> |
Bycycle myBicycle = new Bicycle(); | BasicRectangle r3 = new Rectangle(100,200,5,-5); |
MountainBike myBike = (MountainBike) myBicycle; | Rectangle r4 = (Rectangle)r3; |
</code> | </code> |
| |
Εδώ ενημερώνουμε τον compiler ότι η μεταβλητή ''myBicycle'' είναι και τύπου ''MountainBike''. Ο προγραμματιστής βεβαιώνει ότι αυτό ισχύει. Την παραπάνω ανάθεση την ονομάζουμε ρητή μετατροπή (//explicit casting//). Εάν δεν ισχύει η παραπάνω μετατροπή, κατά την εκτέλεση του προγράμματος θα παραχθεί μία εξαίρεση (//exception//). Θα δούμε πιο κάτω τι είναι και πως διαχειριζόμαστε τις εξαιρέσεις. | Σε αυτή την περίπτωση ο προγραμματιστής βεβαιώνει τον //compiler// ότι η μεταβλητή ''r4'' είναι και τύπου ''Rectangle''. Την παραπάνω ανάθεση την ονομάζουμε ρητή μετατροπή (//explicit casting//). Επειδή δεν ισχύει η παραπάνω μετατροπή, κατά την εκτέλεση του προγράμματος θα παραχθεί μία εξαίρεση (//exception//). Θα δούμε πιο κάτω τι είναι οι εξαιρέσεις και πως τις διαχειριζόμαστε. |
| |
Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα, χωρίς να παραχθεί εξαίρεση είναι ο εξής: | Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα, χωρίς να παραχθεί εξαίρεση είναι ο παρακάτω. Εδώ η μετατροπή γίνεται αφού πρώτα γίνει έλεγχος ότι το αντικείμενο για το οποίο θα γίνει μετατροπή τύπου είναι και του νέου τύπου. Η μετατροπή θα γίνει μόνο εφόσον ο έλεγχος επιτύχει. |
| |
<code java> | <code java> |
Bycycle myBicycle = new Bicycle(); | BasicRectangle r3 = new Rectangle(100,200,5,-5); |
MountainBike myBike; | Rectangle r4; |
if (myBicycle instanceof MountainBike) { | if (r3 instanceof Rectangle) { |
myBike = (MountainBike)myBicycle; | r4 = (Rectangle)r3; |
} | } |
</code> | </code> |
| |
|Προηγούμενο: [[ :java:inheritance | Κληρονομικότητα ]] | Επόμενο: [[ :java:inheritance_subclassing_vs_encapsulating | Κριτήριo χρήσης της κληρονομικότητας ]]| | |Προηγούμενο: [[ :java:inheritance | Κληρονομικότητα ]] | [[:toc | Περιεχόμενα]] | Επόμενο: [[ :java:inheritance_subclassing_vs_encapsulating | Κριτήριo χρήσης της κληρονομικότητας ]]| |