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
java:inner_classes [2016/02/11 14:30]
gthanos [Δημιουργία αντικειμένων της εσωτερικής κλάσης στην εξωτερική κλάση]
java:inner_classes [2021/04/12 05:31]
gthanos
Line 1: Line 1:
 ====== Μη στατικές εμφωλευμένες κλάσεις ====== ====== Μη στατικές εμφωλευμένες κλάσεις ======
  
-Οι μη στατικές εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις (inner classes) αποτελούν την γενικότερη περίπτωση εμφώλευσης μίας κλάσης μέσα σε μία άλλη κλάση. Δείτε το παρακάτω παράδειγμα απεικόνισης των ζυγών στοιχείων ενός πίνακα 15 στοιχείων με χρήση μίας εσωτερικής κλάσης η οποία υλοποιεί το interface [[https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html|Iterator]]:+Οι μη στατικές εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις (inner classes) αποτελούν την γενικότερη περίπτωση εμφώλευσης μίας κλάσης μέσα σε μία άλλη κλάση. Ένας συνήθης λόγος (αλλα όχι ο μοναδικός) για τον οποίο επιδιώκουμε να χρησιμοποιήσουμε εμφωλευμένες κλάσεις είναι όταν θέλουμε να ορίσουμε επιπλέον κλάσεις των οποίων δεν θέλουμε ή δεν έχουμε λόγο να αποκαλύψουμε ότι υπάρχουν. Για παράδειγμαας υποθέσουμε ότι θέλουμε να κατασκευάσουμε μία διπλά συνδεδεμένη λίστα η οποία μπορεί να αποθηκεύσει οποιονδήποτε τύπο όμοιων αντικειμένων. 
 +Η λίστα θα χρειαστεί να έχει τις βοηθητικές κλάσεις  
 +  - την κλάση που περιγράφει τον κόμβο της λίστας και  
 +  - μία κλάση τύπου //iterator// για την διάτρεξη της λίστας 
 +Οι δύο παραπάνω κλάσεις εξυπηρετεί να δηλωθούν ως εσωτερικές κλάσεις αποκρύπτοντας την ύπαρξη τους. Ο χρήστης της κλάσης απαιτείται μόνο να γνωρίζει την κλάση της λίστας και πως μπορεί να διαχειριστεί ένα αντικείμενο τύπου [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]]. Όλα τα υπόλοιπα είναι λεπτομέρειες τα οποία δεν αφορούν τον προγραμματιστή-χρήστη της κλάσης. 
  
-<code java DataStructure.java> +Δείτε τον παρακάτω κώδικα που την υλοποιεί. 
-public class DataStructure {+ 
 +<code java LinkedList.java> 
 +/* A linked list with sentinels at head and tail. 
 + */ 
 +public class LinkedList<E> { 
 +  private Node<E> head, tail; 
 +  int size;
      
-  // Create an array +  public LinkedList() { 
-  private final static int SIZE 15+    head new Node<>(null, null, null)
-  private int[] arrayOfInts = new int[SIZE];+    tail = new Node<>(null, head, null); 
 +    head.setNext(tail); 
 +    size = 0; 
 +  }
      
-  public DataStructure() +  private class Node<E> 
-    // fill the array with ascending integer values +    private Node<E> next, prev; 
-    for (int i = 0SIZE; i++) { +    private E e; 
-      arrayOfInts[i] i;+   
 +    public Node(Node<E> nxt, Node<E> prv, E elem) { 
 +      next = nxt; 
 +      prev = prv; 
 +      e elem;
     }     }
 +    
 +    public Node<E> getNext() { return next;}
 +    public void setNext(Node<E> nxt) { next = nxt; }
 +    public Node<E> getPrev() {return prev;}
 +    public void setPrev(Node<E> prv) { prev = prv; }
 +    public E getElement() { return e; }
 +    public void setElement(E elem) { e = elem; }
   }   }
      
-  public void printEven() {+  private class Iterator<E> implements java.util.Iterator<E> { 
 +    Node<E> curr;
          
-    // Print out values of even indices of the array +    public Iterator(Node<E> c) { 
-    DataStructureIterator iterator = this.new EvenIterator(); +      curr = c;
-    while (iterator.hasNext()) { +
-      System.out.print(iterator.next() + " ");+
     }     }
-    System.out.println(); 
-  } 
-   
-  interface DataStructureIterator extends java.util.Iterator<Integer> { }  
- 
-  // Inner class implements the DataStructureIterator interface, 
-  // which extends the Iterator<Integer> interface 
-   
-  private class EvenIterator implements DataStructureIterator { 
-     
-    // Start stepping through the array from the beginning 
-    private int nextIndex = 0; 
-     
     public boolean hasNext() {     public boolean hasNext() {
-       +      if(curr.getNext() !tail) 
-      // Check if the current element is the last in the array +        return true; 
-      return (nextIndex <SIZE - 1); +      return false
-    }     +    } 
-     +    public next() { 
-    public Integer next() { +      curr curr.getNext(); 
-       +      return curr.getElement(); 
-      // Record a value of an even index of the array +    } 
-      Integer retValue Integer.valueOf(arrayOfInts[nextIndex]); +    public void remove() { 
-       +      curr.getPrev().setNext(curr.getNext()); 
-      // Get the next even element +      curr.getNext().setPrev(curr.getPrev())
-      nextIndex += 2+      curr = curr.getPrev();
-      return retValue;+
     }     }
-     
-    public void remove() { } 
   }   }
      
-  public static void main(String s[]) { +  Iterator<E> iterator() { 
-     +    return new Iterator<E>(head);
-    // Fill the array with integer values and print out only +
-    // values of even indices +
-    DataStructure ds = new DataStructure(); +
-    ds.printEven();+
   }   }
-} +   
-</code> +  // append in the end 
- +  public boolean add(E elem{ 
-<WRAP todo center 80% round> Σε αναλογία, δημιουργήστε την εσωτερική κλάση **OddIterator** και τη μέθοδο **printOdd()** για την εκτύπωση των μονών αριθμών του πίνακα.  +    Node<Eplus new Node<E>(tail, tail.getPrev(), elem)
-</WRAP> +    tail.getPrev().setNext(plus)
- +    tail.setPrev(plus); 
-===== Δημιουργία αντικειμένων της εσωτερικής κλάσης ===== +    size++
- +    return true;
-==== Δημιουργία αντικειμένων της εσωτερικής κλάσης στην εξωτερική κλάση ==== +
- +
-Απαραίτητη προϋπόθεση για να δημιουργηθεί ένα αντικείμενο της εσωτερικής κλάσης είναι να υπάρχει ένα αντικείμενο της εξωτερικής κλάσης. Δεν μπορείτε να έχετε δηλαδή οποιαδήποτε αντικείμενο της εσωτερικής κλάσης χωρίς αυτό να συνδυαστεί με ένα αντικείμενο της εξωτερικής κλάσης. +
- +
-Δείτε το παρακάτω παράδειγμα δημιουργίας ενός αντικειμένου της εσωτερικής κλάσης μέσα στον κατασκευαστή της εξωτερικής κλάσης +
- +
-<code java OuterClass.java> +
-public class OuterClass { +
- +
-  int outerClassField+
-  InnerClass ic+
- +
-  public OuterClass(int field{ +
-    outerClassField = field+
-    ic = new InnerClass(field*2);+
   }   }
      
-  class InnerClass +  public boolean add(int index, E elem) 
-    int innerClassField+    if(index>size) 
-     +      return false
-    public InnerClass(int field) { +    Node<E> curr = head.next; 
-      innerClassField field;+    for(int i=0; curr != tail && i<index; i++) { 
 +      curr curr.next;
     }     }
 +    Node<E> plus = new Node<E>(curr, curr.prev, elem);
 +    curr.prev.next = plus;
 +    curr.prev = plus;
 +    size++;
 +    return true;
   }   }
      
-  public String toString() { +  public boolean contains(E elem) { 
-    return "outerClassField: "+outerClassField+", innerClassField: "+ic.innerClassField;+    Iterator<E> it = iterator(); 
 +    while(it.hasNext()) { 
 +      E e = it.next(); 
 +      if( e.equals(elem) ) 
 +        return true; 
 +    } 
 +    return false;
   }   }
      
-  public static void main(String []args) { +  public int indexOf(E elem) { 
-    OuterClass outer new OuterClass(10); +    Iterator<E> it iterator(); 
-    System.out.println(outer)+    int index = -1; 
-  }   +    while(it.hasNext()) { 
-+      E e it.next(); 
- +      index++
-</code> +      ife.equals(elem) 
- +        return index;
-==== Δημιουργία αντικειμένων της εσωτερικής κλάσης από άλλες κλάσεις ή στατικές μεθόδους ==== +
- +
-Κατ' αρχήν, το πρώτο το οποίο θα πρέπει να σημειώσουμε είναι ότι ένα αντικείμενο της εσωτερικής κλάσης μπορεί να δημιουργηθεί **ΜΟΝΟ ΕΦΟΣΟΝ** υπάρχει ένα αντικείμενο της εξωτερικής κλάσηςΕπομένως, για να δημιουργήσετε ένα αντικείμενο της εσωτερικής κλάσης θα πρέπει να έχετε ήδη ένα αντικείμενο της εξωτερικής κλάσης. Δείτε το παρακάτω παράδειγμα. +
- +
-<code java OuterClass.java> +
-public class OuterClass { +
-  int outer;   +
- +
-  public OuterClass(int o+
-    outer = o    +
-  } +
- +
-  class InnerOuterClass { +
-    int inner+
-     +
-    public InnerOuterClass(int o{ +
-      inner = o;+
     }     }
 +    return -1;
   }   }
      
-+  int size() { 
-</code> +    return size;
- +
-<code java TestOuterClass.java> +
-public class TestOuterClass { +
-  public static void main(String args[]) { +
-    OuterClass outer = new OuterClass(5);                            //line 3 +
-    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4)//line 4+
   }   }
 } }
 </code> </code>
  
-Αρχικά, στην γραμμή 3 δείτε πως δημιουργούμε ένα αντικείμενο της κλάσης **OuterClass**. Στη συνέχεια με δεδομένο ότι έχουμε δημιουργήσει το αντικείμενο τύπου **OuterClass** στο οποίο δείχνει η μεταβλητή outer δημιουργούμε ένα νέο αντικείμενο της εσωτερικής κλάσης, όπως παρακάτω. Παρατηρήστε την ιδιαίτερη σύνταξη δημιουργίας αντικειμένων της εσωτερικής κλάσης +Το παρακάτω πρόγραμμα επιχειρεί να δημιουργήσει μία λίστα με 20 τυχαίους αριθμούς και στη συνέχεια να τους εκτυπώσει χρησιμοποιώντας τον Iterator της λίστας. Παρατηρήστε ότι σε κανένα σημείου του προγράμματος δεν αποκαλύπτεται η ύπαρξη των εσωτερικών κλάσεων //Node// και //Iterator//. Η μεταβλητή //it// παραπέμπει στο interface [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]].
-<code java+
-OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4); +
-</code>+
  
-<WRAP todo 80% round center> +<code java LinkedListUsage.java> 
-Είναι προφανές ότι μπορούμε να φτιάξουμε πολλαπλά αντικείμενα της εσωτερικής κλάσης, με την προϋπόθεση ότι έχουμε τουλάχιστον ένα αντικείμενο της εξωτερικής κλάσης. Τι γίνεται όμως αν παραλείψετε να αρχικοποιήσετε την μεταβλητή της γονικής κλάσης, όπως παρακάτω: +import java.util.*;
-<code java TestOuterClass.java> +
-public class TestOuterClass { +
-  public static void mian(String args[]) { +
-    OuterClass outer;                                                //line 3 +
-    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(4)//line 4 +
-  } +
-+
-</code> +
-Δοκιμάστε το. +
-</WRAP>+
  
-Οι εσωτερικές κλάσεις μπορούν να έχουν προσδιοριστές πρόσβασης (//public, protected, package-private, private//) όπως και τα πεδία της κλάσης. Θα εξηγήσουμε αναλυτικά στη συνέχεια τη σημασία των προσδιοριστών πρόσβασης για τις εσωτερικές κλάσεις. +public class LinkedListUsage 
- +  public static final int SIZE = 16
-===== Πρόσβαση στα πεδία της εξωτερικής κλάσης (από την εσωτερική κλάση) ===== +  public static final int RANGE = 8 * SIZE;
- +
-Κάθε εσωτερική κλάση έχει πρόσβαση στα πεδία και τις μεθόδους της εξωτερικής κλάσης, **ανεξάρτητα από τους προσδιοριστές πρόσβασης που έχουν αυτά**. Διαφορετικά, κάθε μέθοδος της εσωτερικής κλάσης μπορεί να έχει πρόσβαση σε μεταβλητές ή μεθόδους της εξωτερικής της κλάσης, ακόμη και εάν αυτές είναι δηλωμένες ως **private**.  +
- +
-<WRAP tip 80% round center> +
-Εάν μία μέθοδος της εσωτερικής κλάσης καλεί μία άλλη μέθοδο η οποία δεν ανήκει στην εσωτερική κλάση, τότε ο compiler αναζητά την μέθοδο στην εξωτερική κλάση. Αν δεν την βρει και στην εξωτερική κλάση τότε εμφανίζει μήνυμα λάθους.  +
- +
-Αντίστοιχα, εάν μία μέθοδος της εσωτερικής κλάσης χρησιμοποιήσει ένα πεδίο που δεν υπάρχει στην εσωτερική κλάση, ο compiler θα το αναζητήσει στην εξωτερική κλάση και μόνο αν δεν το βρει ούτε εκεί θα εκτυπώσει ένα μήνυμα λάθους. +
-</WRAP> +
- +
-Δείτε το παρακάτω παράδειγμα προσβασιμότητας των πεδίων της εξωτερικής κλάσης από την εσωτερική κλάση: +
- +
-<code java OuterClassAccess.java> +
-public class OuterClassAccess +
-  private int outerPriv; +
-  int outerPckgPriv; +
-  protected int outerProt+
-  public int outerPub; +
-  InnerClass ic;+
      
-  private void setOuterPriv(int v) { outerPriv v; } +  static void print(LinkedList<Integer> list){ 
-  private int getOuterPriv() { return outerPriv} +    Iterator<Integer> it list.iterator(); 
-   +     
-  void setOuterPckgPriv(int v) { outerPckgPriv = v; } +    // Print list 
-  int getPckgOuterPriv() { return outerPckgPriv;+    while(it.hasNext()) { 
-   +      System.out.print(it.next()+"  "); 
-  protected void setOuterProt(int v) { outerProt = v; } +    
-  protected int getOuterProt() { return outerProt; } +    System.out.println();
-   +
-  public void setOuterPub(int v{ outerPub = v} +
-  public int getOuterPub() { return outerPub;   +
-   +
-  public OuterClassAccess() { +
-     ic = new InnerClass(1,2,3,4); +
-     ic.setOuterClassFields(5,6,7,8);+
   }   }
      
-  public String toString() { +  public static void main(String[] args) { 
-    return "outerPriv: "+outerPriv+", outerPckgPriv: "+outerPckgPriv+ +    Random rand = new Random( new Date().getTime()); 
-           ", outerProt: "+outerProt+", outerPub: "+outerPub; +    LinkedList<Integer> list = new LinkedList<>()
-  } +    for(int i=0; i<SIZE; i++) { 
-   +      int value rand.nextInt(RANGE)
-  private class InnerClass { +      int pos rand.nextInt(list.size()+1);  
-   +      System.out.format("Adding %d at %d\n", value, pos)
-    public InnerClass(int p, int pp, int pr, int pu) { +      list.add(pos,value); 
-      outerPriv p+      print(list);
-      outerPckgPriv pp+
-      outerProt = pr+
-      outerPub = pu;+
     }     }
 +    print(list);
          
-    public void setOuterClassFields(int p, int pp, int pr, int pu) { +    // Remove all elements less than RANGE/2 
-      setOuterPriv(p); +    System.out.println("Remove values < "+RANGE/2); 
-      setOuterPckgPriv(pp); +    Iterator<Integerit list.iterator()
-      setOuterProt(pr); +    while(it.hasNext()) 
-      setOuterPub(pu); +      int value it.next(); 
-    }     +      //System.out.println("value: "+value); 
-  } +      if(value < RANGE/2) { 
-   +        //System.out.println("RMV: "+value); 
-  public static void main(String args[]) { +        it.remove(); 
-    OuterClassAccess oc = new OuterClassAccess(); +      }
-    System.out.println(oc); +
-  } +
-+
-</code> +
- +
-<WRAP important 80% center round> +
-Από το παραπάνω παράδειγμα, παρατηρούμε ότι η εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία και τις μεθόδους της εξωτερικής κλάσης, ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά. +
-</WRAP> +
-==== Κρύβοντας τα πεδία της εξωτερικής κλάσης ==== +
- +
-Στο προηγούμενο παράδειγμα είδαμε την προσβασιμότητα στα πεδία και τις μεθόδους της εξωτερικής κλάσηςΤι γίνεται όμως όταν υπάρχει μία μέθοδος που καλεί μία άλλη μέθοδο η οποία υπάρχει τόσο στη εσωτερική όσο και στην εξωτερική κλάση. Σε αναλογία τι γίνεται όταν μία μέθοδος καλεί ένα πεδίο το οποίο υπάρχει στην εσωτερική και την εξωτερική κλάσηΤο παρακάτω παράδειγμα απαντά στις παραπάνω απορίες. +
- +
-<code java ShadowTest.java> +
-public class ShadowTest +
- +
-  public int 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);+
     }     }
 +    print(list);
          
-    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> </code>
  
-<WRAP tip 80% center round> +<WRAP todo center 80% round> **Εργασία για το σπίτι:** Επιχειρήσετε να συμπληρώσετε την κλάση LinkedList ώστε να ικανοποιεί το interface [[http://docs.oracle.com/javase/8/docs/api/java/util/List.html|java.util.List]].
-Το παραπάνω εξηγεί ικανοποιήτικα τον λόγο που πιθανόν να θέλετε να βάλετε ένα "περιοριστικό" προσδιοριστή πρόσβασης σε μία εσωτερική κλάση (συνήθως //private//). Ο λόγος είναι ότι με τον εν λόγο προσδιοριστή πρόσβασης αποκλείετε τη πρόσβαση στην εσωτερική κλάση από άλλες κλάσεις, κρύβοντας τον κώδικα που αφορά μόνο την συγκεκριμένη εξωτερική κλάση.+
 </WRAP> </WRAP>
  
  
-===== Πρόσβαση από την εξωτερική κλάση σε πεδία της εσωτερικής κλάσης ===== +|Προηγούμενο: [[ :java:nested_classes| Εμφωλευμένες κλάσεις  ]] |  [[:toc|Περιεχόμενα]]  |Επόμενο: [[ :java:inner_class_objects | Δημιουργία αντικειμένων της εσωτερικής κλάσης ]]|
- +
-Το παρακάτω παράδειγμα εξηγεί την προσβασιμότητα της εξωτερικής κλάσης σε πεδία και μεθόδους της εσωτερικής κλάσης. +
- +
-<code java OuterClass.java> +
-public class OuterClass { +
-  int outer; +
-  InnerOuterClass innerObj; +
- +
-  public OuterClass(int o) { +
-    outer = o; +
-    innerObj = new InnerOuterClass(); +
-    innerObj.innerPriv = 10; +
-    innerObj.innerProt = 20; +
-    innerObj.innerPub = 30; +
-    System.out.println(innerObj); +
-  } +
- +
-  class InnerOuterClass { +
-    private int innerPriv; +
-    protected int innerProt; +
-    public int innerPub; +
-     +
-    private void setInnerPriv(int priv) { innerPriv = priv; } +
-    protected void setInnerProt(int prot) { innerProt = prot; } +
-    public void setInnerPub(int pub) { innerPub = pub; } +
-    public String toString() {  +
-      return "innerPriv"+innerPriv+", innerProt"+innerProt+ +
-             ", innerPub"+innerPub;  +
-    }     +
-  } +
-   +
-  public static void main(String[] args) { +
-    OuterClass outer = new OuterClass(5); +
-  }   +
-+
-</code> +
- +
-Όπως θα παρατηρήσετε αν μεταγλωττίσετε και εκτελέσετε το πρόγραμμα η εξωτερική κλάση έχει απόλυτη πρόσβαση στα πεδία και τις μεθόδους της εσωτερικής κλάσης ανεξάρτητα από τον προσδιοριστή πρόσβασης που έχουν αυτά. +
- +
-<WRAP important 80% center round> +
-  * H εσωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εξωτερικής κλάσης+
-  * Η εξωτερική κλάση έχει πρόσβαση σε όλα τα πεδία της εσωτερικής κλάσης. +
-Οι προσδιοριστές πρόσβασης **δεν εισάγουν κανένα περιορισμό** στον προσδιορισμό της προσβασιμότητας των πεδίων και των μεθόδων της εσωτερικής κλάσης από την εξωτερική κλάση και αντίστροφα. +
-</WRAP> +
- +
-===== Πρόσβαση από άλλες κλάσεις σε πεδία της εσωτερικής κλάσης ===== +
- +
-Ο παρακάτω κώδικας επιχειρεί να δημιουργήσει ένα αντικείμενο μίας κλάσης εσωτερικής κλάσης από μία άλλη κλάση. Σε αυτή την περίπτωση και __με την προϋπόθεση ότι η εσωτερική κλάση είναι συνολικά προσβάσιμη__ από την κλάση που επιχειρεί να δημιουργήσει το αντικείμενο, η προσβασιμότητα των πεδίων και των μεθόδων της εσωτερικής κλάσης εξαρτάται από τους προσδιοριστές πρόσβασης που έχουν αυτά. Δείτε το παρακάτω παράδειγμα. +
- +
-<code java OuterClass.java> +
-public class OuterClass { +
-  int outer; +
-  InnerOuterClass innerObj; +
- +
-  public OuterClass(int o) { +
-    outer = o; +
-    innerObj = new InnerOuterClass(); +
-    innerObj.innerPriv = 10; +
-    innerObj.innerProt = 20; +
-    innerObj.innerPub = 30; +
-    System.out.println(innerObj); +
-  } +
- +
-  class InnerOuterClass { +
-    private int innerPriv; +
-    protected int innerProt; +
-    public int innerPub; +
-     +
-    private void setInnerPriv(int priv) { innerPriv = priv; } +
-    protected void setInnerProt(int prot) { innerProt = prot; } +
-    public void setInnerPub(int pub) { innerPub = pub; } +
-    public String toString() {  +
-      return "innerPriv: "+innerPriv+", innerProt: "+innerProt+ +
-             ", innerPub: "+innerPub;  +
-    }     +
-  } +
-   +
-+
-</code> +
- +
-<code java TestOuterClass.java> +
-public class TestOuterClass { +
-  public static void main(String args[]) { +
-    OuterClass outer = new OuterClass(5); +
-    OuterClass.InnerOuterClass inner = outer.new InnerOuterClass(); +
-    inner.setInnerPriv(4); +
-    inner.setInnerProt(5); +
-    inner.setInnerPub(6); +
-    System.out.println(inner);     +
-  } +
-+
-</code> +
- +
-Κατά συνέπεια, για την προσβασιμότητα των πεδίων και των μεθόδων της εσωτερικής κλάσης από μία άλλη κλάση ισχύουν τα εξής: +
-  - Η εσωτερική κλάση θα πρέπει να είναι συνολικά προσβάσιμη. +
-  - Με την προϋπόθεση ότι ισχύει το **1.**, ισχύουν οι [[java:access_modifiers|κανόνες προσβασιμότητας]] που ορίζονται από προσδιοριστές πρόσβασης. +
- +
java/inner_classes.txt · Last modified: 2021/04/12 04:31 (external edit)