User Tools

Site Tools


java:static_nested_classes

Στατικές εμφωλευμένες κλάσεις

Η συγκεκριμένη ενότητα είναι προαιρετική και μπορείτε να την παραλήψετε κατά την ανάγνωση της θεωρείας του μαθήματος.

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

  1. Οι μη στατικές εμφωλευμένες κλάσεις δεν μπορούν να έχουν στατικά πεδία ή στατικές μεθόδους. Αν θέλετε να ορίσετε ένα στατικό πεδίο ή μέθοδο στην εμφωλευμένη κλάση θα πρέπει να την ορίσετε ως static. Προσπαθήστε να ορίσετε ένα στατικό πεδία μέσα σε μία μη στατική εμφωλευμένη κλάση και δείτε το μήνυμα του compiler.
  2. Αν θέλετε να δημιουργήσετε ένα αντικείμενο ή να καλέσετε μεθόδους της εμφωλευμένης κλάσης μέσα από μία στατική μέθοδο της εξωτερικής κλάσης θα πρέπει η εμφωλευμένη κλάση να έχει οριστεί ως static.

Δείτε το παρακάτω παράδειγμα, όπου η εσωτερική στατική κλάση έχει πρόσβαση στο στατικό πεδίο της εξωτερικής κλάσης.

NonStaticOuterClass.java
public class NonStaticOuterClass {
  static int outer;
  StaticInnerClass innerObj;
 
  public NonStaticOuterClass(int o) {
    outer = o;
    java.util.Random r = new java.util.Random();
    innerObj = new StaticInnerClass(r.nextInt(100), r.nextInt(100), r.nextInt(100));
  }
 
  public String toString() {
     return "outer: "+outer+" | "+innerObj.toString();
  }  
 
  public static class StaticInnerClass {
    private int innerPriv;
    protected int innerProt;
    public int innerPub;
 
    public StaticInnerClass(int innerPriv, int innerProt,int innerPub) {
      this.innerPriv = innerPriv;
      this.innerProt = innerProt;
      this.innerPub = innerPub;
    }    
 
    public String toString() { 
      return "innerPriv: "+innerPriv+", innerPub: "+innerPub +", innerProt: "+innerProt; 
    }    
  }
 
  public static void main(String args[]) {
    NonStaticOuterClass myOuter = new NonStaticOuterClass(10);
    System.out.println(myOuter.innerObj.toString());
    StaticInnerClass myInnerObj = new StaticInnerClass(15, 20, 35);
    System.out.println(myInnerObj);
 
    NonStaticOuterClass.StaticInnerClass myInnerObj2 = new NonStaticOuterClass.StaticInnerClass(100, 200, 300);
    System.out.println(myInnerObj2);
  }  
}

Από την μεταγλώττιση και εκτέλεση του παραπάνω κώδικα παρατηρούμε ότι

  • αν και η κλάση StaticInnerClass δηλώνεται ως static μπορεί να δημιουργηθούν πολλαπλά αντικείμενα της κλάσης αυτής.
  • Τα αντικείμενα της στατικής εσωτερικής κλάσης ΔΕΝ ανήκουν στην εξωτερική κλάση, όπως συμβαίνει στις μη στατικές κλάσεις. Στο παραπάνω παράδειγμα, η σύνδεση μεταξύ εσωτερικής στατικής και εξωτερικής μη στατικής κλάσης έγκειται στο γεγονός ότι ένα πεδίο της εξωτερικής κλάσης είναι του τύπου της εσωτερικής κλάσης.
  • Η τελευταία γραμμή της μεθόδου main δείχνει ότι οι στατικές εσωτερικές κλάσεις μπορούν να οριστούν ανεξάρτητα από αντικείμενα της εξωτερικής τους κλάσης. Επιβεβαιώστε την αλήθεια του ισχυρισμού μεταγλωττίζοντας και εκτελώντας τον παραπάνω κώδικα.

Πρόσβαση στα στατικά και μη στατικά πεδία της εξωτερικής κλάσης

Σημαντική ιδιαιτερότητα των static εμφωλευμένων κλάσεων είναι ότι δεν έχουν απευθείας πρόσβαση στις μη-στατικές μεταβλητές της εξωτερικής κλάσης στην οποία ανήκουν, αλλά μόνο στις στατικές μεταβλητές αυτής. H πρόσβαση στις μη-στατικές μεταβλητές μπορεί να γίνει μέσα από ένα αντικείμενο της εξωτερικής κλάσης.

Το παρακάτω παράδειγμα δείχνει ότι πως μπορείτε να έχετε πρόσβαση στις μη στατικές μεταβλητές της εξωτερικής κλάσης μέσω ενός αντικειμένου της κλάσης αυτής.

NonStaticOuterClass.java
public class NonStaticOuterClass {
  static int s_int;
  int ns_int;
 
  public NonStaticOuterClass(int s, int ns) {
    s_int = s;
    ns_int = ns;
  }
 
  public String toString() {
     return "static: "+s_int+", non-static: "+ns_int;
  }  
 
  public static class StaticInnerClass {
 
    void setOuterClass(NonStaticOuterClass outerObj, int o) {
      outerObj.s_int = o;
      outerObj.ns_int = 2*o;
    }
 
    void setOuterClassDirectly(int o) {
      s_int = o;
      //sn_int = 2*o;      // comment out this line and compile again
    }
 
    public String toString() { 
      return "s_int: "+s_int; 
    }    
  }  
}

Δημιουργία αντικειμένων της εμφωλευμένης στατικής κλάσης από μία τρίτη κλάση διαφορετική της εξωτερικής κλάσης

Πως όμως μπορείτε να δημιουργήσετε αντικείμενα μίας εμφωλευμένης στατικής κλάσης μέσα σε μία άλλη κλάση, διαφορετική της εξωτερικής κλάσης; Δείτε το παρακάτω παράδειγμα κώδικα και παρατηρήστε την διαφορά σε σχέση με την δημιουργία αντικειμένων που ανήκουν σε μη στατικές κλάσεις.

TestNonStaticOuterClass.java
public class TestNonStaticOuterClass {
  public static void main(String args[]) {
    NonStaticOuterClass.StaticInnerClass inner = new NonStaticOuterClass.StaticInnerClass();
    inner.setOuterClassDirectly(6);
    System.out.println(inner);
  }
}
java/static_nested_classes.txt · Last modified: 2020/03/16 09:55 (external edit)