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 [2017/05/12 14:20]
gthanos removed
java:inner_classes [2017/05/12 14:45] (current)
gthanos
Line 1: Line 1:
-====== ​Δημιουργία αντικειμένων της ​εσωτερικής κλάσης ======+====== ​Μη στατικές εμφωλευμένες κλάσεις ======
  
-===== Δημιουργία αντικειμένων της ​εσωτερικής κλάσης στην εξωτερική κλάση ​=====+Οι μη στατικές εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις (inner classes) αποτελούν την γενικότερη περίπτωση εμφώλευσης μίας κλάσης μέσα σε μία άλλη κλάση. Ας υποθέσουμε ότι θέλουμε να κατασκευάσουμε μία διπλά συνδεδεμένη λίστα η οποία μπορεί να αποθηκεύσει οποιονδήποτε τύπο όμοιων ​αντικειμένων
 +Η λίστα θα χρειαστεί να έχει δύο βοηθητικές κλάσεις  
 +  - την κλάση που περιγράφει τον ​κόμβο της λίστας και  
 +  - μία ​κλάση τύπου //​iterator//​ για την διάτρεξη της λίστας 
 +Οι δύο παραπάνω κλάσεις ​εξυπηρετεί να δηλωθούν ως εσωτερικές κλάσεις αποκρύπτοντας την υλοποίηση των κλάσεων αυτών. Το παραπάνω επιτρέπει η λίστα να είναι συμβατή με τα interfaces [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​List.html|java.util.List]] και [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Iterator.html|java.util.Iterator]]. Δείτε τον παρακάτω κώδικα που την υλοποιεί.
  
-Απαραίτητη προϋπόθεση για να δημιουργηθεί ένα αντικείμενο της εσωτερικής κλάσης είναι να υπάρχει ένα αντικείμενο της εξωτερικής κλάσης. Δεν μπορείτε να έχετε δηλαδή οποιαδήποτε αντικείμενο της εσωτερικής κλάσης χωρίς αυτό να συνδυαστεί με ένα αντικείμενο της εξωτερικής κλάσης. +<code java LinkedList.java> 
- +public class LinkedList<​E> ​
-Δείτε το παρακάτω παράδειγμα δημιουργίας ενός αντικειμένου της εσωτερικής κλάσης μέσα στον κατασκευαστή της εξωτερικής κλάσης +  ​private Node<​E>​ head, tail
- +   
-<code java OuterClass.java> +  public ​LinkedList() { 
-public class OuterClass ​{ +    ​head new Node<>​(null,​ null, null)
- +    ​tail = new Node<>​(null,​ head, null); 
-  ​int outerClassField+    head.setNext(tail);
-  ​InnerClass ic; +
- +
-  public ​OuterClass(int field) { +
-    ​outerClassField ​field+
-    ​ic = new InnerClass(field*2);+
   }   }
   ​   ​
-  class InnerClass ​+  ​private ​class Node<​E> ​
-    ​int innerClassField;+    ​private Node<​E>​ next, prev; 
 +    private E e; 
 +   
 +    public Node(Node<​E>​ nxt, Node<​E>​ prv, E elem) { 
 +      next = nxt; 
 +      prev = prv; 
 +      e = elem; 
 +    }
     ​     ​
-    public ​InnerClass(int field) { +    public ​Node<​E>​ getNext() {return next;} 
-      ​innerClassField ​field;+    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; } 
 +  } 
 +   
 +  private class Iterator<​E>​ implements java.util.Iterator { 
 +    Node<​E>​ curr; 
 +    public Iterator(Node<​E>​ c) { 
 +      curr = c; 
 +    } 
 +    public boolean hasNext() { 
 +      if(curr.getNext() != tail) 
 +        return true; 
 +      return false; 
 +    } 
 +    public E next() { 
 +      curr = curr.getNext();​ 
 +      return curr.getElement();​ 
 +    } 
 +    public void remove() { 
 +      curr.getPrev().setNext(curr.getNext());​ 
 +      curr.getNext().setPrev(curr.getPrev());​ 
 +      ​curr null;
     }     }
   }   }
   ​   ​
-  ​public String toString() { +  ​Iterator<​E>​ iterator() { 
-    return ​"​outerClassField:​ "​+outerClassField+",​ innerClassField:​ "​+ic.innerClassField;+    return ​new Iterator<​E>​(head);
   }   }
   ​   ​
-  public ​static ​void main(String []args) { +  ​// append in the end 
-    ​OuterClass outer = new OuterClass(10); +  ​public void add(E elem) { 
-    System.out.println(outer); +    ​Node<​E>​ plus = new Node<​E>​(tail, tail.getPrev(), elem); 
-  ​} ​  +    tail.getPrev().setNext(plus); 
-+    ​tail.setPrev(plus);
- +
-</​code>​ +
- +
-===== Δημιουργία αντικειμένων της εσωτερικής κλάσης από άλλες κλάσεις ή στατικές μεθόδους ===== +
- +
-Προηγούμενα αναφέρθηκε ότι για να δημιουργηθεί ένα αντικείμενο της εσωτερικής κλάσης θα πρέπει να υπάρχει ένα αντικείμενο της εξωτερικής κλάσηςΔείτε πως μπορείτε να δημιουργήσετε σε μία στατική μέθοδο ​(//όπως είναι η μέθοδος **main**//ένα αντικείμενο της εσωτερικής κλάσης με βάση την εξωτερική κλάση. +
- +
-<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 contains(E elem) 
-    ​int innerClassField+    ​Iterator<​E>​ it = iterator()
-    ​ +    ​while(it.hasNext()) { 
-    public InnerClass(int field) { +      ​E e it.next()
-      ​innerClassField ​field+      if( e.equals(elem) 
-    } +        return ​true;
-     +
-    public String toString() { +
-      return ​"​[innerClassField:​ "​+innerClassField+"​]"​;+
     }     }
 +    return false;
   }   }
   ​   ​
-  public ​String toString() { +  public ​int indexOf(E elem) { 
-    ​return "​outerClassField:​ "+outerClassField+" "+ic.toString();+    ​Iterator<​E>​ it = iterator();​ 
 +    int index = -1; 
 +    while(it.hasNext()) { 
 +      E e = it.next();​ 
 +      index++
 +      if( e.equals(elem
 +        return index; 
 +    } 
 +    return -1;
   }   }
 } }
- 
-class TestOuterClass { 
-  public static void main(String []args) { 
-    OuterClass outer = new OuterClass(10);​ 
-    System.out.println(outer);​ 
-    OuterClass.InnerClass inner = outer.new InnerClass(4);​ 
-    System.out.println(inner.toString());​ 
-  } 
-} 
- 
 </​code>​ </​code>​
  
-Αρχικάδημιουργούμε ένα ​αντικείμενο της κλάσης **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 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>​ +
-Σε αυτή την περίπτωση λαμβάνετε από τον μεταγλωττιστή ένα μήνυμα λάθους της μορφής +
-<​code>​ +
-OuterClass.java:29: error: variable outer might not have been initialized +
-    OuterClass.InnerClass inner = outer.new InnerClass(4); ​//line 4 +
-                                  ^ +
-1 error +
-</code> +
-Δοκιμάστε το. +
-</​WRAP>​+
  
-Οι εσωτερικές κλάσεις μπορούν να έχουν προσδιοριστές πρόσβασης (//public, protected, package-private,​ private//) όπως και τα πεδία της κλάσης. Θα εξηγήσουμε αναλυτικά στη συνέχεια τη σημασία των προσδιοριστών πρόσβασης για τις εσωτερικές κλάσεις. 
  
-| Προηγούμενο : [[ :java:inner_classes ​Μη στατικές εμφωλευμένες κλάσεις ​ ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο:​ [[ :java:inner_class_access ​Προσβασιμότητα πεδίων και μεθόδων μεταξύ ​εσωτερικής και εξωτερικής κλάσης ]]  |+|Προηγούμενο:​ [[ :java:nested_classesΕμφωλευμένες κλάσεις ​ ]] |  [[:​toc|Περιεχόμενα]] ​ |Επόμενο:​ [[ :java:inner_class_objects ​Δημιουργία αντικειμένων της εσωτερικής κλάσης ]]|
java/inner_classes.1494598826.txt.gz · Last modified: 2017/05/12 14:20 by gthanos