Table of Contents

Η κλάση Object

Όλες οι κλάσεις στην Java είναι απόγονοι της κλάσης Object. Για παράδειγμα, η κλάση Integer κληρονομεί την κλάση Νumber που κληρονομεί την κλάση Object.

     java.lang.Object
           |
           ----|
               v
        java.lang.Number
               |
               ----|
                   v
            java.lang.Integer 

Λόγω της ύπαρξης της κλάσης Object όλα τα αντικείμενα στην Java κληρονομούν συγκεκριμένες μεθόδους που ορίζονται στην κλάση αυτή. Τις μεθόδους αυτές μπορείτε αν θέλετε να τις επαναορίσετε στις κλάσεις που δημιουργείτε ή να τις αφήσετε ως έχουν. Οι κυριότερες μέθοδοι της κλάσης Object είναι οι εξής:

  getClass().getName() + '@' + Integer.toHexString(hashCode())

Έλεγχος ισότητας μεταξύ δύο αντικειμένων

Ας υποθέσουμε ότι έχουμε δύο αντικείμενα της κληρονομούμενης κλάσης Rectangle η οποία με τη σειρά της διαθέτει ένα πεδίο τύπου Point.

Θέλουμε να συγκρίνουμε τα δύο αυτά αντικείμενα μόνο ως προς την ισότητα. Για να το κάνουμε αυτό έχουμε δύο επιλογές:

  // 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;
  }
  // 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;
  }

Όμως ο επαναορισμός της μεθόδου equals δεν αρκεί ώστε να σηματοδοτήσει την ισότητα μεταξύ δύο αντικείμενων. Με βάση την τεκμηρίωση της μεθόδου equals, όταν επαναορίζουμε τη μέθοδο equals είναι απαραίτητο να ορίσουμε ξανά και τη μέθοδο hashCode, ώστε δύο ίδια αντικείμενα να έχουν και την ίδια επιστρεφόμενη τιμή της συνάρτησης hashCode. Ο επαναορισμός της συνάρτησης hashCode έχει ως εξής (ενδεικτική υλοποίηση):

  // equals method for class Point
  @Override
  public int hashCode() {
    int hash = 3;
    hash = 19 * hash + this.x;
    hash = 17 * hash + this.y;
    return hash;
  }  
  // 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;
  } 

Μπορείτε να κατεβάσετε εδώ την τελική διαμόρφωση των κλάσεων Point και Rectangle μετά την προσθήκη των παραπάνω συναρτήσεων. Παρακάτω δίνεται ένα πρόγραμμα που ελέγχει την ισότητα δύο αντικειμένων τύπου Rectangle, μετά την προσθήκη των συναρτήσεων equals και hashCode όπως περιγράφονται παραπάνω:

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());
 
  }
} 

Βάλτε σε σχόλια τις μεθόδους equals και hashCode στις παραπάνω κλάσεις και ελέγξτε τι εκτυπώνει το παραπάνω πρόγραμμα σε αυτή την περίπτωση.