java:type_casting

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
Last revision Both sides next revision
java:type_casting [2016/02/15 04:54]
gthanos
java:type_casting [2017/02/16 13:33]
gthanos [Κριτήρια χρήσης της κληρονομικότητας ως εργαλείο ανάπτυξης λογισμικού]
Line 7: Line 7:
 </​code>​ </​code>​
  
-Από την παραπάνω δήλωση η μεταβλητή ''​myBike''​ είναι τύπου ''​MountainBike''​. Επειδή όμως ο τύπος ''​MountainBike''​ κληρονομεί από την μεταβλητή ''​Bicycle''​ **__η συγκεκριμένη μεταβλητή είναι και τύπου Bicycle__**. Επομένως θα μπορούσαμε να γράψουμε+Από την παραπάνω δήλωση η μεταβλητή ''​myBike''​ είναι τύπου ''​MountainBike''​. Επειδή όμως ο τύπος ''​MountainBike''​ κληρονομεί από την μεταβλητή ''​Bicycle''​ **__η συγκεκριμένη μεταβλητή είναι και τύπου Bicycle__**. Επομένωςθα μπορούσαμε να γράψουμε
  
 <code java> <code java>
Line 15: Line 15:
 </​code>​ </​code>​
  
-Την παραπάνω ανάθεση την ονομάζουμε //Implicit Casting// διότι αναθέτουμε μία μεταβλητή ενός τύπου δεδομένων (''​myBike''​) σε μία μεταβλητή γονικού τύπου δεδομένων (''​myBicycle''​),​ χωρίς type casting.+Την παραπάνω ανάθεση την ονομάζουμε ​άρρητη μετατροπή (//implicit casting//διότι αναθέτουμε μία μεταβλητή ενός τύπου δεδομένων (''​myBike''​) σε μία μεταβλητή γονικού τύπου δεδομένων (''​myBicycle''​),​ χωρίς ​να ορίζουμε μία μετατροπή τύπου (//type cast//).
  
 Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα Ας δοκιμάσουμε το ανάποδο παράδειγμα τώρα
Line 24: Line 24:
 </​code>​ </​code>​
  
-Σε αυτή την περίπτωση ο compiler διαμαρτύρεται,​ διότι η μεταβλητή ''​myBicycle''​ είναι τύπου ''​Bicycle''​ και δεν είναι απαραίτητο ότι είναι και τύπου ''​MountainBike''​. Αν θέλουμε να ξεπεράσουμε το παραπάνω ​πρόβλημα θα πρέπει να γράψουμε το εξής:+Σε αυτή την περίπτωση ο compiler διαμαρτύρεται,​ διότι η μεταβλητή ''​myBicycle''​ είναι τύπου ''​Bicycle''​ και δεν είναι απαραίτητο ότι είναι και τύπου ''​MountainBike''​. Αν θέλουμε να ξεπεράσουμε το παραπάνω ​μήνυμα λάθους του compiler ​θα πρέπει να γράψουμε το εξής:
  
 <code java> <code java>
Line 31: Line 31:
 </​code>​ </​code>​
  
-Εδώ ενημερώνουμε τον compiler ότι η μεταβλητή ''​myBicycle''​ είναι και τύπου ''​MountainBike'',​ λαμβάνοντας ο προγραμματιστής την ευθύνη ότι ​κάτι τέτοιο ​ισχύει. Εάν δεν ισχύει ​κάτι τέτοιο ​κατά την εκτέλεση του προγράμματος θα παραχθεί μία εξαίρεση (exception)*. Θα δούμε πιο κάτω τι είναι και πως διαχειριζόμαστε τις εξαιρέσεις.+Εδώ ενημερώνουμε τον compiler ότι η μεταβλητή ''​myBicycle''​ είναι και τύπου ''​MountainBike'',​ λαμβάνοντας ο προγραμματιστής την ευθύνη ότι ​αυτό ισχύει. Εάν δεν ισχύεικατά την εκτέλεση του προγράμματος θα παραχθεί μία εξαίρεση (exception)*. Θα δούμε πιο κάτω τι είναι και πως διαχειριζόμαστε τις εξαιρέσεις.
  
 Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα,​ χωρίς να παραχθεί εξαίρεση είναι ο εξής: Ένας πιο ασφαλής τρόπος για να επαναλάβουμε τον παραπάνω κώδικα,​ χωρίς να παραχθεί εξαίρεση είναι ο εξής:
Line 45: Line 45:
 ===== Κριτήρια χρήσης της κληρονομικότητας ως εργαλείο ανάπτυξης λογισμικού ===== ===== Κριτήρια χρήσης της κληρονομικότητας ως εργαλείο ανάπτυξης λογισμικού =====
  
-Ας επανέλθουμε στο παράδειγμα του ορθογωνίου παραλληλογράμμου το οποίο έχουμε συναντήσει αρκετές φορές στο παρελθόν.+Ας επανέλθουμε στο παράδειγμα του ορθογωνίου παραλληλογράμμου το οποίο έχουμε συναντήσει αρκετές φορές στο παρελθόν ​και ας προσπαθήσουμε να δημιουργήσουμε την κλάση ενός [[wp>​Cuboid|κυβοειδούς]] με χρήση της υφιστάμενης κλάσης του [[java:​class|ορθογωνίου παραλληλογράμμου]].
  
 +Πριν ξεκινήσουμε την υλοποίηση θα πρέπει να αποφασίσουμε εάν θέλουμε να δημιουργήσουμε το κυβοειδές χρησιμοποιώντας ως μεταβλητή της νέας κλάσης ένα αντικείμενο της κλάσης //​Rectangle//​ ή επιθυμούμε να επεκτείνουμε την κλάση //​Rectangle//​ μέσω της νέας κλάσης. Δείτε παρακάτω τις δύο παραλλαγές της κλάσης //Cuboid// με και χωρίς κληρονομικότητα.
  
 +<code java Cuboid.java>​
 +public class Cuboid {
 +  Rectangle rec;
 +  int length;
 +  ​
 +  public Cuboid(int l, int w, int h) {
 +    rec = new Rectangle(w,​h);​
 +    length = l;
 +  }
 +  ​
 +  public int getLength() { return length; }
 +  public void setLength(int l) { length = l; }
 +  ​
 +  public int volume() { return length * rec.area(); }
 +}
 +</​code>​
 +
 +ή 
 +
 +<code java Cuboid.java>​
 +public class Cuboid extends Rectangle {
 +  int length;
 +  ​
 +  public Cuboid(int l, int w, int h) {
 +    super(w,h);
 +    length = l;
 +  }
 +  ​
 +  public int getLength() { return length; }
 +  public void setLength(int l) { length = l; }
 +  ​
 +  public int volume() { return length * area(); }
 +}
 +</​code>​
 +
 +Οι παραπάνω δύο κλάσεις μεταγλωττίζονται και παράγουν το ίδιο λειτουργικό αποτέλεσμα. Το ερώτημα είναι ποια από τις δύο μεθόδους θα προτιμήσουμε. Η απάντηση είναι απλή και συνίσταται στο εξής: Εάν ο νέος τύπος δεδομένων που προκύπτει ανήκει στον τύπο δεδομένων της αρχικής κλάσης τότε μπορούμε να χρησιμοποιήσουμε την κληρονομικότητα ως μέθοδο ανάπτυξης. Εάν όμως ο νέος τύπος δεδομένων δεν αποτελεί τύπο δεδομένων και της παραπάνω κατηγορίας.
 +
 +Εκφράζοντας το παραπάνω με κώδικα,​ η παρακάτω σχέση θα πρέπει να στέκει και λογικά εκτός από συντακτικά.
 +<code java>
 +InheritedClass child = new InheritedClass();​
 +ParentClass parent = child;
 +</​code>​
 +
 +Για παράδειγμα,​ [[java:​inheritance|στο αρχικό παράδειγμα της κληρονομικότητας]],​ από την κλάση Bicycle προκύπτουν οι κλάσεις //​MountainBike//,​ //​RoadBike//​ και //​TandemBike//​. Και οι 3 νέες κλάσεις είναι τύπου Bicycle, καθώς αποτελούν εξειδικεύσεις της γενικής κλάσης του ποδηλάτου. ​
 +
 +Στην περίπτωση που περιγράψαμε παραπάνω κάτι τέτοιο δεν ισχύει. Αν και η κλάση του κυβοειδούς χρειάζεται ένα ορθογώνιο παραλληλόγραμμο για να περιγραφεί,​ το κυβοειδές δεν είναι ορθογώνιο παραλληλόγραμμο. Δεν μπορούμε να πάμε δηλαδή από το κυβοειδές προς το ορθογώνιο παραλληλόγραμμο διατηρώντας τις βασικές ιδιότητες του κυβοειδούς. Το κυβοειδές είναι ένα τρισδιάστατο σχήμα, ενώ το ορθογώνιο παραλληλόγραμμο δισδιάστατο. Το κυβοειδές αποτελεί μία εντελώς νέα οντότητα σε σχέση με το ορθογώνιο παραλληλόγραμμο. Μπορούμε να το εκφράσουμε με την χρήση της κλάσης ενός ορθογώνιου παραλληλογράμμου,​ χωρίς όμως η χρήση του ορθογωνίου παραλληλογράμμου να είναι απαραίτητη ή να συνδέεται άμεσα με το κυβοειδές.
 +
 +|Προηγούμενο:​ [[ :​java:​inheritance | Κληρονομικότητα ]] | [[ :toc | Περιεχόμενα ]]  | Επόμενο:​ [[ :​java:​inheritance_subclassing_vs_encapsulating | Κριτήριo χρήσης της κληρονομικότητας]]|
java/type_casting.txt · Last modified: 2017/02/16 13:34 by gthanos