java:inner_classes

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
Next revision Both sides next revision
java:inner_classes [2016/02/11 14:41]
gthanos [Δημιουργία αντικειμένων της εσωτερικής κλάσης από άλλες κλάσεις ή στατικές μεθόδους]
java:inner_classes [2016/02/26 11:15]
127.0.0.1 external edit
Line 175: Line 175:
   }   }
 } }
 +</​code>​
 +Σε αυτή την περίπτωση λαμβάνετε από τον μεταγλωττιστή ένα λάθος της μορφής
 +<​code>​
 +OuterClass.java:​29:​ error: variable outer might not have been initialized
 +    OuterClass.InnerClass inner = outer.new InnerClass(4);​ //line 4
 +                                  ^
 +1 error
 </​code>​ </​code>​
 Δοκιμάστε το. Δοκιμάστε το.
Line 250: Line 257:
 Από το παραπάνω παράδειγμα,​ παρατηρούμε ότι η εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία και τις μεθόδους της εξωτερικής κλάσης,​ ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά. Από το παραπάνω παράδειγμα,​ παρατηρούμε ότι η εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία και τις μεθόδους της εξωτερικής κλάσης,​ ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά.
 </​WRAP>​ </​WRAP>​
-==== Κρύβοντας τα πεδία της εξωτερικής κλάσης ==== 
- 
-Στο προηγούμενο παράδειγμα είδαμε την προσβασιμότητα στα πεδία και τις μεθόδους της εξωτερικής κλάσης. Τι γίνεται όμως όταν υπάρχει μία μέθοδος που καλεί μία άλλη μέθοδο η οποία υπάρχει τόσο στη εσωτερική όσο και στην εξωτερική κλάση. Σε αναλογία τι γίνεται όταν μία μέθοδος καλεί ένα πεδίο το οποίο υπάρχει στην εσωτερική και την εξωτερική κλάση; Το παρακάτω παράδειγμα απαντά στις παραπάνω απορίες. 
- 
-<code java ShadowTest.java>​ 
-public class ShadowTest { 
- 
-  public int x = 100; 
- 
-  class FirstLevel { 
- 
-    public int x = 200; 
- 
-    void methodInFirstLevel(int x) { 
-      System.out.println("​x = " + x); 
-      System.out.println("​this.x = " + this.x); 
-      System.out.println("​ShadowTest.this.x = " + ShadowTest.this.x);​ 
-    } 
-    ​ 
-    String printX() { return "X in FirstLevel is "​+x+"​ and "​+ShadowTest.this.printX();​ } 
-  } 
-  ​ 
-  String printX() { return "X in ShadowTest is "+x; } 
- 
-  public static void main(String args[]) { 
-    ShadowTest st = new ShadowTest();​ 
-    ShadowTest.FirstLevel fl = st.new FirstLevel();​ 
-    fl.methodInFirstLevel(23);​ 
-    ​ 
-    System.out.println(st.printX());​ 
-    System.out.println(fl.printX());​ 
-  } 
-} 
-</​code>​ 
- 
-==== Χρήση προσδιοριστών πρόσβασης στην εσωτερική κλάση ==== 
- 
-Στο προηγούμενο παράδειγμα δοκιμάστε να αλλάξετε τον προσδιοριστή πρόσβασης της κλάσης **InnerOuterClass** από package private σε private. Σε αυτή την περίπτωση θα παρατηρήσετε ότι η κλάση **TestOuterClass** δεν μεταγλωττίζεται. Συγκεκριμένα,​ o compiler εμφανίζει το παρακάτω μήνυμα λάθους,​ σημειώνοντας ότι ο προσδιοριστής πρόσβασης **private** δεν επιτρέπει τη πρόσβαση από μία άλλη κλάση στο συγκεκριμένο περιεχόμενο της **OuterClass**. Γενικότερα,​ ισχύουν οι κανόνες για τους προσδιοριστές πρόσβασης όπως αυτοί αναφέρονται [[java:​access_modifiers|εδώ]]. 
- 
-<​code>​ 
-TestOuterClass.java:​6:​ error: OuterClass.InnerOuterClass has private access in OuterClass 
-    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4);​ 
-              ^ 
-TestOuterClass.java:​6:​ error: OuterClass.InnerOuterClass has private access in OuterClass 
-    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4);​ 
-</​code>​ 
- 
-<WRAP tip 80% center round> 
-Το παραπάνω εξηγεί ικανοποιήτικα τον λόγο που πιθανόν να θέλετε να βάλετε ένα "​περιοριστικό"​ προσδιοριστή πρόσβασης σε μία εσωτερική κλάση (συνήθως //​private//​). Ο λόγος είναι ότι με τον εν λόγο προσδιοριστή πρόσβασης αποκλείετε τη πρόσβαση στην εσωτερική κλάση από άλλες κλάσεις,​ κρύβοντας τον κώδικα που αφορά μόνο την συγκεκριμένη εξωτερική κλάση. 
-</​WRAP>​ 
- 
  
 ===== Πρόσβαση από την εξωτερική κλάση σε πεδία της εσωτερικής κλάσης ===== ===== Πρόσβαση από την εξωτερική κλάση σε πεδία της εσωτερικής κλάσης =====
Line 340: Line 296:
 </​code>​ </​code>​
  
-Όπως θα παρατηρήσετε αν μεταγλωττίσετε και εκτελέσετε το πρόγραμμα η εξωτερική κλάση έχει απόλυτη πρόσβαση στα πεδία και τις μεθόδους της εσωτερικής κλάσης ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά.+Όπως θα παρατηρήσετε αν μεταγλωττίσετε και εκτελέσετε το πρόγραμμα η εξωτερική κλάση έχει απόλυτη πρόσβαση στα πεδία και τις μεθόδους της εσωτερικής κλάσης ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά. Η διαφορά ανάμεσα στην πρόσβαση της εξωτερικής κλάσης στα πεδία της εσωτερικής γίνεται μέσω ενός αντικειμένου της εξωτερικής κλάσης.
  
 <WRAP important 80% center round> <WRAP important 80% center round>
   * H εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εξωτερικής κλάσης.   * H εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εξωτερικής κλάσης.
-  * Η εξωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εσωτερικής κλάσης.+  * Η εξωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εσωτερικής κλάσης. Η πρόσβαση στα πεδία αυτά γίνεται μέσω ενός αντικειμένου της εξωτερικής κλάσης.
 Οι προσδιοριστές πρόσβασης **δεν εισάγουν κανένα περιορισμό** στον προσδιορισμό της προσβασιμότητας των πεδίων και των μεθόδων της εσωτερικής κλάσης από την εξωτερική κλάση και αντίστροφα. Οι προσδιοριστές πρόσβασης **δεν εισάγουν κανένα περιορισμό** στον προσδιορισμό της προσβασιμότητας των πεδίων και των μεθόδων της εσωτερικής κλάσης από την εξωτερική κλάση και αντίστροφα.
 </​WRAP>​ </​WRAP>​
Line 355: Line 311:
 public class OuterClass { public class OuterClass {
   int outer;   int outer;
-  ​InnerOuterClass ​innerObj;+  ​InnerClass ​innerObj;
  
   public OuterClass(int o) {   public OuterClass(int o) {
     outer = o;     outer = o;
-    innerObj = new InnerOuterClass();+    innerObj = new InnerClass();
     innerObj.innerPriv = 10;     innerObj.innerPriv = 10;
     innerObj.innerProt = 20;     innerObj.innerProt = 20;
Line 366: Line 322:
   }   }
  
-  class InnerOuterClass ​{+  class InnerClass ​{
     private int innerPriv;     private int innerPriv;
     protected int innerProt;     protected int innerProt;
Line 387: Line 343:
   public static void main(String args[]) {   public static void main(String args[]) {
     OuterClass outer = new OuterClass(5);​     OuterClass outer = new OuterClass(5);​
-    OuterClass.InnerOuterClass ​inner = outer.new ​InnerOuterClass();+    OuterClass.InnerClass ​inner = outer.new ​InnerClass();
     inner.setInnerPriv(4);​     inner.setInnerPriv(4);​
     inner.setInnerProt(5);​     inner.setInnerProt(5);​
Line 400: Line 356:
   - Με την προϋπόθεση ότι ισχύει το **1.**, ισχύουν οι [[java:​access_modifiers|κανόνες προσβασιμότητας]] που ορίζονται από προσδιοριστές πρόσβασης.   - Με την προϋπόθεση ότι ισχύει το **1.**, ισχύουν οι [[java:​access_modifiers|κανόνες προσβασιμότητας]] που ορίζονται από προσδιοριστές πρόσβασης.
  
 +==== Χρήση προσδιοριστών πρόσβασης στην εσωτερική κλάση ====
 +
 +Στο προηγούμενο παράδειγμα δοκιμάστε να αλλάξετε τον προσδιοριστή πρόσβασης της κλάσης **InnerClass** από package private σε private. Σε αυτή την περίπτωση θα παρατηρήσετε ότι η κλάση **TestOuterClass** δεν μεταγλωττίζεται. Συγκεκριμένα,​ o compiler εμφανίζει το παρακάτω μήνυμα λάθους,​ σημειώνοντας ότι ο προσδιοριστής πρόσβασης **private** δεν επιτρέπει τη πρόσβαση από μία άλλη κλάση στο συγκεκριμένο περιεχόμενο της **OuterClass**. Γενικότερα,​ ισχύουν οι κανόνες για τους προσδιοριστές πρόσβασης όπως αυτοί αναφέρονται [[java:​access_modifiers|εδώ]].
 +
 +<​code>​
 +TestOuterClass.java:​6:​ error: OuterClass.InnerOuterClass has private access in OuterClass
 +    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4);​
 +              ^
 +TestOuterClass.java:​6:​ error: OuterClass.InnerOuterClass has private access in OuterClass
 +    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4);​
 +</​code>​
 +
 +<WRAP tip 80% center round>
 +Το παραπάνω εξηγεί ικανοποιητικά τον τρόπο με τον οποίο μπορείτε να αποκλείσετε την πρόσβαση στην εσωτερική κλάση από άλλες κλάσεις πέραν της εξωτερικής. Ορίζοντας την εσωτερική κλάση ως **private** αυτή είναι προσβάσιμη μόνο από την εξωτερική της κλάση.
 +</​WRAP>​
 +
 +==== Επαναορίζοντας (ή κρύβοντας..) τα πεδία της εξωτερικής κλάσης στην εσωτερική κλάση ====
 +
 +Στο προηγούμενο παράδειγμα είδαμε την προσβασιμότητα στα πεδία και τις μεθόδους της εξωτερικής κλάσης. Τι γίνεται όμως όταν υπάρχει μία μέθοδος που καλεί μία άλλη μέθοδο η οποία υπάρχει τόσο στη εσωτερική όσο και στην εξωτερική κλάση. Σε αναλογία τι γίνεται όταν μία μέθοδος καλεί ένα πεδίο το οποίο υπάρχει στην εσωτερική και την εξωτερική κλάση; Το παρακάτω παράδειγμα απαντά στις παραπάνω απορίες.
 +
 +<code java ShadowTest.java>​
 +public class ShadowTest {
 +
 +  public int x = 100;
 +
 +  class FirstLevel {
 +
 +    public int x = 200;
 +
 +    void methodInFirstLevel(int x) {
 +      System.out.println("​x = " + x);
 +      System.out.println("​this.x = " + this.x);
 +      System.out.println("​ShadowTest.this.x = " + ShadowTest.this.x);​
 +    }
 +    ​
 +    String printX() { return "X in FirstLevel is "​+x+"​ and "​+ShadowTest.this.printX();​ }
 +  }
 +  ​
 +  String printX() { return "X in ShadowTest is "+x; }
 +
 +  public static void main(String args[]) {
 +    ShadowTest st = new ShadowTest();​
 +    ShadowTest.FirstLevel fl = st.new FirstLevel();​
 +    fl.methodInFirstLevel(23);​
 +    ​
 +    System.out.println(st.printX());​
 +    System.out.println(fl.printX());​
 +  }
 +}
 +</​code>​
  
 +|Προηγούμενο:​ [[ :​java:​static_nested_classes| Στατικές εμφωλευμένες κλάσεις ​ ]] | Επόμενο:​ [[ :​java:​local_inner_classes | Τοπικές εμφωλευμένες κλάσεις ]]|
java/inner_classes.txt · Last modified: 2017/05/12 14:45 by gthanos