User Tools

Site Tools


java:object_class

Differences

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

Link to this comparison view

Next revision
Previous revision
java:object_class [2016/02/15 16:35] – created gthanosjava:object_class [2021/03/22 07:36] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Η κλάση Object ====== ====== Η κλάση Object ======
  
-Όλες οι κλάσεις στην Java είναι απόγονοι της κλάσης [[http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html|Object]]. Λόγω της κλάση //Object// όλα τα αντικείμενα στην Java κληρονομούν συγκεκριμένες μεθόδους που ορίζονται στην κλάση αυτή. Τις μεθόδους αυτές μπορείτε αν θέλετε να τις επαναορίσετε στις κλάσεις που δημιουργείτε ή να τις αφήσετε ως έχουν. Οι κυριότερες μέθοδοι της κλάσης //Object// είναι οι εξής: +Όλες οι κλάσεις στην Java είναι απόγονοι της κλάσης [[http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html|Object]]. Για παράδειγμα, η κλάση [[http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html|Integer]] κληρονομεί την κλάση [[http://docs.oracle.com/javase/7/docs/api/java/lang/Number.html|Νumber]] που κληρονομεί την κλάση //Object//.  
-  * **public boolean equals(Object obj):** Η μέθοδος ελέγχει αν δύο αντικείμενα είναι ίδια. Εάν δεν την επαναορίσετε, η συγκεκριμένη μέθοδος ελέγχει εάν το αντικείμενο που την καλεί ταυτίζεται με το όρισμα που λαμβάνει. Μόνο στην περίπτωση που αυτά είναι ίδια επιστρέφει **true**, διαφορετικά επιστρέφει **false**. + 
-  * **public int hashCode():** Επιστρέφει έναν αριθμό (hash) για το συγκεκριμένο αντικείμενο. Ο αριθμός αυτός θα πρέπει να είναι μοναδικός για κάθε αντικείμενο. Κάθε κλήση της συγκεκριμένης μεθόδου σε ένα αντικείμενο πρέπει να επιστρέφει πάντα το ίδιο αποτέλεσμα. Δεν χρειάζεται να επαναορίσετε τη συγκεκριμένη συνάρτηση+<code> 
-  * **public String toString():** Επιστρέφει μία αναπαράσταση σε μορφή [[http://docs.oracle.com/javase/7/docs/api/java/lang/String.html|String]] για το αντικείμενο. Η default υλοποίηση της μεθόδου ισοδυναμεί με το παρακάτω:+     java.lang.Object 
 +           | 
 +           ----| 
 +               v 
 +        java.lang.Number 
 +               | 
 +               ----| 
 +                   v 
 +            java.lang.Integer  
 +</code> 
 + 
 +Λόγω της ύπαρξης της κλάσης //Object// όλα τα αντικείμενα στην Java κληρονομούν συγκεκριμένες μεθόδους που ορίζονται στην κλάση αυτή. Τις μεθόδους αυτές μπορείτε αν θέλετε να τις επαναορίσετε στις κλάσεις που δημιουργείτε ή να τις αφήσετε ως έχουν. Οι κυριότερες μέθοδοι της κλάσης //Object// είναι οι εξής: 
 +  * **public boolean equals(Object obj):** Η μέθοδος ελέγχει αν δύο αντικείμενα είναι ίδια. Η μέθοδος ελέγχει εάν το αντικείμενο που την καλεί ταυτίζεται με το όρισμα που λαμβάνει. Μόνο στην περίπτωση που αυτά είναι ταυτόσημα επιστρέφει **true**, διαφορετικά επιστρέφει **false**. Εάν δύο διακριτά αντικείμενα έχουν πεδία με ίδιες τιμές η μέθοδος επιστρέφει **false**. 
 +  * **public int hashCode():** Επιστρέφει έναν θετικό ακέραιο (hash value) για το συγκεκριμένο αντικείμενο. Ο αριθμός αυτός είναι μοναδικός για κάθε αντικείμενο.  
 +  * **[[[[:java:toString|public String toString()]]:** Επιστρέφει μία αναπαράσταση σε μορφή [[http://docs.oracle.com/javase/7/docs/api/java/lang/String.html|String]] για το αντικείμενο. Η //default// υλοποίηση της μεθόδου ισοδυναμεί με την παρακάτω έκφραση. Συνιστάται ο επαναορισμός της μεθόδου της συγκεκριμένης κλάσης σε όλες τις κλάσεις που δημιουργείτε. Ο επαναορισμός της συγκεκριμένης μεθόδου μπορεί να χρησιμοποιηθεί για την επιστροφή ενός αλφαριθμητικού που περιέχει τις τιμές των πεδίων του εκάστοτε αντικειμένου.
 <code java> <code java>
   getClass().getName() + '@' + Integer.toHexString(hashCode())   getClass().getName() + '@' + Integer.toHexString(hashCode())
 </code> </code>
-  * **public final Class<?> getClass():** Επιστρέφει ένα αντικείμενο της κλάσης [[http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html|Class]]. Η κλάση //Class// συγκεντρώνει πληροφορίες αναφορικά με τα χαρακτηριστικά της κάθε κλάσης.+  * **public final Class<?> getClass():** Επιστρέφει ένα αντικείμενο της κλάσης [[http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html|Class]]. Η κλάση //Class// συγκεντρώνει πληροφορίες αναφορικά με τα χαρακτηριστικά της κλάσης του αντικειμένου. 
 +  * Οι παρακάτω μέθοδοι συνδέονται με τη λειτουργία των νημάτων (//threads//
 +    * **public final void notify()** 
 +    * **public final void notifyAll()** 
 +    * **public final void wait()** 
 +    * **public final void wait(long timeout)** 
 +    * **public final void wait(long timeout, int nanos)** 
 + 
 + 
 + 
 + 
 +===== Έλεγχος ισότητας μεταξύ δύο αντικειμένων ===== 
 + 
 +Ας υποθέσουμε ότι έχουμε δύο αντικείμενα της [[java:inheritance|κληρονομούμενης κλάσης]]  [[https://courses.e-ce.uth.gr/ECE326/doku.php?do=export_code&id=java:inheritance&codeblock=2|Rectangle]] η οποία με τη σειρά της διαθέτει ένα πεδίο τύπου [[https://courses.e-ce.uth.gr/ECE326/doku.php?do=export_code&id=java:inheritance&codeblock=1|Point]]. 
 + 
 +Θέλουμε να συγκρίνουμε τα δύο αυτά αντικείμενα μόνο ως προς την ισότητα. Για να το κάνουμε αυτό έχουμε δύο επιλογές: 
 +  * **χρήση του τελεστή =**: Ο τελεστής = ελέγχει οι δύο μεταβλητές αριστερά και δεξιά του τελεστή δείχνουν στο ίδιο αντικείμενο. Ως εκ τούτου δεν μπορεί να χρησιμοποιηθεί στη συγκεκριμένη περίπτωση. 
 +  * **χρήση της μεθόδου equals:** Θα πρέπει να επαναορίσουμε τη μέθοδο equals, ώστε όταν συγκρίνονται δύο αντικείμενα που έχουν τα ίδια πεδία η μέθοδος να επιστρέφει true. Εδώ θα πρέπει να σημειώσουμε ότι εφόσον η κλάση περιέχει και ένα πεδίο τύπου Point, μόνο εάν και τα πεδία τύπου Point των δύο αντικειμένων δείχνουν σε διαφορετικά αντικείμενα που έχουν κοινές τιμές τα δύο αντικείμενα τύπου Rectangle θα είναι ίδια. Ενδεικτικές υλοποιήσεις της μεθόδου equals των κλάσεων Point και Rectangle δίνονται παρακάτω: 
 + 
 +<code java> 
 +  // equals method for class Point 
 +  @Override 
 +  public boolean equals(Object o) { 
 +    if(o == null) 
 +      return false; 
 +    if(o instanceof Point) { 
 +      Point p = (Point)o; 
 +      if(p.x == x && p.y == y) 
 +        return true; 
 +    } 
 +    return false; 
 +  } 
 +</code> 
 + 
 +<code java> 
 +  // equals method for class Rectangle 
 +  @Override 
 +  public boolean equals(Object o) { 
 +    if(o == null) 
 +      return false; 
 +    if(o instanceof Rectangle) { 
 +      Rectangle r = (Rectangle)o; 
 +      if(r.width == width && r.height == height && r.origin.equals(origin)) 
 +        return true; 
 +    } 
 +    return false; 
 +  } 
 +</code> 
 + 
 + 
 +Όμως ο επαναορισμός της μεθόδου equals δεν αρκεί ώστε να σηματοδοτήσει την ισότητα μεταξύ δύο αντικείμενων. [[https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)|Με βάση την τεκμηρίωση της μεθόδου equals]], όταν επαναορίζουμε τη μέθοδο equals είναι απαραίτητο να ορίσουμε ξανά και τη μέθοδο hashCode, ώστε δύο ίδια αντικείμενα να έχουν και την ίδια επιστρεφόμενη τιμή της συνάρτησης hashCode. Ο επαναορισμός της συνάρτησης hashCode έχει ως εξής (ενδεικτική υλοποίηση): 
 + 
 +<code java> 
 +  // equals method for class Point 
 +  @Override 
 +  public int hashCode() { 
 +    int hash = 3; 
 +    hash = 19 * hash + this.x; 
 +    hash = 17 * hash + this.y; 
 +    return hash; 
 +  }   
 +</code> 
 + 
 +<code java> 
 +  // equals method for class Rectangle 
 +  @Override 
 +  public int hashCode() { 
 +    int hash = 7; 
 +    hash += 13 * width; 
 +    hash += 17 * height; 
 +    hash = 31 * hash + Objects.hashCode(this.origin); 
 +    return hash; 
 +  }  
 +</code> 
 + 
 +Μπορείτε να κατεβάσετε {{:java:equalsoverride.zip|εδώ}} την τελική διαμόρφωση των κλάσεων Point και Rectangle μετά την προσθήκη των παραπάνω συναρτήσεων. Παρακάτω δίνεται ένα πρόγραμμα που ελέγχει την ισότητα δύο αντικειμένων τύπου Rectangle, μετά την προσθήκη των συναρτήσεων equals και hashCode όπως περιγράφονται παραπάνω: 
 + 
 +<code java EqualityDemo.java> 
 +public class EqualityDemo { 
 + 
 +  public static void main(String[] args) { 
 +    
 +    // create two Rectangle objects with the same parameters 
 +    Rectangle r1 = new Rectangle(100, 200, 5, -5); 
 +    Rectangle r2 = new Rectangle(100, 200, 5, -5); 
 +     
 +    // objctes are different. We fail here. 
 +    if( r1 == r2) 
 +      System.out.println("r1 == r2"); 
 +     
 +    // Equals function works! 
 +    if(r1.equals(r2)) 
 +      System.out.println("r1 equals r2"); 
 +    if(r2.equals(r1)) 
 +      System.out.println("r1 equals r2"); 
 +     
 +    // hashCode return values are also equal. 
 +    System.out.format("r1 hashCode: 0x%x\n", r1.hashCode()); 
 +    System.out.format("r2 hashCode: 0x%x\n", r2.hashCode()); 
 +     
 +  } 
 +}  
 +</code> 
 + 
 +<WRAP tip 80% center round> 
 +Βάλτε σε σχόλια τις μεθόδους equals και hashCode στις παραπάνω κλάσεις και ελέγξτε τι εκτυπώνει το παραπάνω πρόγραμμα σε αυτή την περίπτωση. 
 +</WRAP> 
  
 +|Προηγούμενο: [[ :java:super_operator | Ο τελεστής super ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[ :java:polymorphism | Στατικός και Δυναμικός Πολυμορφισμός ]]|
java/object_class.1455554109.txt.gz · Last modified: 2016/02/15 16:35 (external edit)