User Tools

Site Tools


java:inner_classes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:inner_classes [2017/02/03 13:59] gthanosjava:inner_classes [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
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; 
 +   
 +  public LinkedList() { 
 +    head = new Node<>(null, null, null); 
 +    tail = new Node<>(null, head, null); 
 +    head.setNext(tail); 
 +    size = 0; 
 +  }
      
-  // Create an array +  private class Node<E> { 
-  private final static int SIZE = 15+    private Node<E> next, prev
-  private int[] arrayOfInts = new int[SIZE];+    private E e;
      
-  public DataStructure() { +    public Node(Node<E> nxt, Node<E> prv, E elem) { 
-    // fill the array with ascending integer values +      next = nxt; 
-    for (int i 0i < SIZE; i++) { +      prev prv
-      arrayOfInts[i] i;+      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() + " ");+    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 = curr.getPrev();
     }     }
-    System.out.println(); 
   }   }
      
-  interface DataStructureIterator extends java.util.Iterator<Integer{ } +  Iterator<E> iterator() { 
 +    return new Iterator<E>(head); 
 +  } 
 +   
 +  // append in the end 
 +  public boolean add(E elem) { 
 +    Node<E> plus = new Node<E>(tail, tail.getPrev(), elem); 
 +    tail.getPrev().setNext(plus); 
 +    tail.setPrev(plus); 
 +    size++; 
 +    return true; 
 +  } 
 +   
 +  public boolean add(int index, E elem) { 
 +    if(index>size) 
 +      return false; 
 +    Node<E> curr = head.next; 
 +    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 boolean contains(E elem) { 
 +    Iterator<E> it = iterator(); 
 +    while(it.hasNext()) { 
 +      E e = it.next(); 
 +      if( e.equals(elem) ) 
 +        return true; 
 +    } 
 +    return false; 
 +  } 
 +   
 +  public int indexOf(E elem) { 
 +    Iterator<E> it = iterator(); 
 +    int index = -1; 
 +    while(it.hasNext()) { 
 +      E e = it.next(); 
 +      index++; 
 +      if( e.equals(elem) ) 
 +        return index; 
 +    } 
 +    return -1; 
 +  } 
 +   
 +  int size() { 
 +    return size; 
 +  } 
 +
 +</code> 
 + 
 +Το παρακάτω πρόγραμμα επιχειρεί να δημιουργήσει μία λίστα με 20 τυχαίους αριθμούς και στη συνέχεια να τους εκτυπώσει χρησιμοποιώντας τον Iterator της λίστας. Παρατηρήστε ότι σε κανένα σημείου του προγράμματος δεν αποκαλύπτεται η ύπαρξη των εσωτερικών κλάσεων //Node// και //Iterator//. Η μεταβλητή //it// παραπέμπει στο interface [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]]. 
 + 
 +<code java LinkedListUsage.java> 
 +import java.util.*;
  
-  // Inner class implements the DataStructureIterator interface, +public class LinkedListUsage { 
-  // which extends the Iterator<Integer> interface+  public static final int SIZE = 16; 
 +  public static final int RANGE = 8 * SIZE;
      
-  private class EvenIterator implements DataStructureIterator {+  static void print(LinkedList<Integer> list){ 
 +    Iterator<Integer> it = list.iterator();
          
-    // Start stepping through the array from the beginning +    // Print list 
-    private int nextIndex = 0; +    while(it.hasNext()) { 
-     +      System.out.print(it.next()+"  ");
-    public boolean hasNext() { +
-       +
-      // Check if the current element is the last in the array +
-      return (nextIndex <= SIZE - 1); +
-    }     +
-     +
-    public Integer next() +
-       +
-      // Record a value of an even index of the array +
-      Integer retValue = Integer.valueOf(arrayOfInts[nextIndex])+
-       +
-      // Get the next even element +
-      nextIndex += 2; +
-      return retValue;+
     }     }
-     +    System.out.println();
-    public void remove() { }+
   }   }
      
-  public static void main(String s[]) {+  public static void main(String[] args) { 
 +    Random rand = new Random( new Date().getTime()); 
 +    LinkedList<Integer> list = new LinkedList<>(); 
 +    for(int i=0; i<SIZE; i++) { 
 +      int value = rand.nextInt(RANGE); 
 +      int pos = rand.nextInt(list.size()+1);  
 +      System.out.format("Adding %d at %d\n", value, pos); 
 +      list.add(pos,value); 
 +      print(list); 
 +    } 
 +    print(list); 
 +     
 +    // Remove all elements less than RANGE/2 
 +    System.out.println("Remove values < "+RANGE/2); 
 +    Iterator<Integer> it = list.iterator(); 
 +    while(it.hasNext()) { 
 +      int value = it.next(); 
 +      //System.out.println("value: "+value); 
 +      if(value < RANGE/2) { 
 +        //System.out.println("RMV: "+value); 
 +        it.remove(); 
 +      } 
 +    } 
 +    print(list);
          
-    // Fill the array with integer values and print out only 
-    // values of even indices 
-    DataStructure ds = new DataStructure(); 
-    ds.printEven(); 
   }   }
 } }
 +
 </code> </code>
  
-<WRAP todo center 80% round> Σε αναλογία, δημιουργήστε την εσωτερική κλάση **OddIterator** και τη μέθοδο **printOdd()** για την εκτύπωση των μονών αριθμών του πίνακα+<WRAP todo center 80% round> **Εργασία για το σπίτι:** Επιχειρήσετε να συμπληρώσετε την κλάση LinkedList ώστε να ικανοποιεί το interface [[http://docs.oracle.com/javase/8/docs/api/java/util/List.html|java.util.List]].
 </WRAP> </WRAP>
  
  
-|Προηγούμενο: [[ :java:static_nested_classesΣτατικές εμφωλευμένες κλάσεις  ]] | Επόμενο: [[ :java:local_inner_classes Τοπικές εμφωλευμένες κλάσεις ]]|+|Προηγούμενο: [[ :java:nested_classesΕμφωλευμένες κλάσεις  ]] |  [[:toc|Περιεχόμενα]]  |Επόμενο: [[ :java:inner_class_objects Δημιουργία αντικειμένων της εσωτερικής κλάσης ]]|
java/inner_classes.1486130381.txt.gz · Last modified: 2017/02/03 13:59 (external edit)