User Tools

Site Tools


java:anon_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:anon_inner_classes [2018/03/21 09:32] – [Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως υλοποίηση ενός interface] gthanosjava:anon_inner_classes [2023/03/23 20:43] (current) – [Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως υλοποίηση ενός interface] gthanos
Line 4: Line 4:
  
 Ανώνυμες εμφωλευμένες κλάσεις μπορούμε να υλοποιήσουμε όταν συντρέχουν ταυτόχρονα οι παρακάτω λόγοι:  Ανώνυμες εμφωλευμένες κλάσεις μπορούμε να υλοποιήσουμε όταν συντρέχουν ταυτόχρονα οι παρακάτω λόγοι: 
-  - επιθυμούμε την υλοποίηση εσωτερικής κλάσης+  - θέλουμε να υλοποιήσουμε μία εσωτερική κλάση. 
-  - η κλάση αυτή υλοποιεί ένα interface ή επεκτείνει μία άλλη κλάση (η κλάση που επεκτείνεται μπορεί να είναι abstract ή όχι) και  +  - η κλάση αυτή υλοποιεί ένα //interface// ή επεκτείνει μία υφιστάμενη κλάση (η κλάση που επεκτείνεται μπορεί να είναι //abstract// ή όχι) και  
-  - από την κλάση αυτή πρόκειται να δημιουργηθεί μόνο ένα αντικείμενο. +  - από την κλάση αυτή επιθυμούμε να δημιουργηθεί μόνο ένα αντικείμενο. 
    
-Σε αυτές τις περιπτώσεις η χρήση ανώνυμων κλάσεων μπορεί να είναι βολική, καθώς συμπιέζει τον όγκο του κώδικα. Από την άλλη πλευρά η εκτεταμένη χρήση ανώνυμων κλάσεων μπορεί να δημιουργήσει κώδικα που είναι δυσανάγνωστος.+Σε αυτές τις περιπτώσεις η χρήση ανώνυμων κλάσεων μπορεί να είναι βολική, καθώς συμπιέζει το μέγεθος του κώδικα. Από την άλλη πλευρά η εκτεταμένη χρήση ανώνυμων κλάσεων μπορεί να δημιουργήσει κώδικα που είναι δυσανάγνωστος.
  
 ===== Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως υλοποίηση ενός interface ===== ===== Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως υλοποίηση ενός interface =====
  
-Στο παρακάτω παράδειγμα ορίζουμε την κλάση **Student** η οποία έχει τα τρία (3) πεδία **firstName**, **lastName**, **AEM**. Στη μέθοδο **//main//** ορίζουμε μία λίστα (ArrayList) από δεδομένα τύπου **Student** τα οποία διαβάζουμε από το αρχείο students.txt. Θέλουμε να ταξινομήσουμε τα δεδομένα της λίστας κατά αύξουσα σειρά με δύο διαφορετικούς τρόπους α)με βάση τη σειρά επώνυμο/όνομα/ΑΕΜ και β) με βάση τη σειρά ΑΕΜ/επώνυμο/όνομα. Η ταξινόμηση των στοιχείων μίας λίστας μπορεί να γίνει με τη βοήθεια της στατικής μεθόδου [[https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)|Collections.sort(java.util.List, java.util.Comparator)]], όπου παρέχεται ένα **συγκριτής** (//comparator//) για την σύγκριση των στοιχείων της λίστας. Η σύγκριση έχει υλοποιηθεί με δύο ανώνυμες κλάσεις που υλοποιούν και οι δύο το //interface// [[https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html|java.util.Comparator]]. +Στο παρακάτω παράδειγμα ορίζουμε την κλάση **Student** η οποία έχει τα τρία (3) πεδία **firstName**, **lastName**, **AEM**. Θέλουμε να ταξινομήσουμε τα δεδομένα της λίστας κατά αύξουσα σειρά με δύο διαφορετικούς τρόπους α) με βάση τη σειρά επώνυμο/όνομα/ΑΕΜ και β) με βάση τη σειρά ΑΕΜ/επώνυμο/όνομα. Η ταξινόμηση των στοιχείων μίας λίστας μπορεί να γίνει με τη βοήθεια της στατικής μεθόδου [[https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)|Collections.sort(java.util.List, java.util.Comparator)]], όπου παρέχεται ένας **συγκριτής** (//comparator//) για την σύγκριση των στοιχείων της λίστας. Η σύγκριση έχει υλοποιηθεί με δύο ανώνυμες κλάσεις που υλοποιούν και οι δύο το //interface// [[https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html|java.util.Comparator]].
- +
-<code students.txt> +
-4596 Super Man +
-5819 Peter Pan +
-1694 Susan Brown +
-7895 Lena Smith +
-3256 Oscar Gonzales +
-1243 Edgar Wallace +
-3265 Kate Gordon +
-4377 Leda Evans +
-1118 David Lerroy +
-8744 Amelia Dray +
-</code>+
  
 <code java Student.java> <code java Student.java>
Line 46: Line 33:
     return String.format("%5d. %s, %s", AEM, lastName, firstName);     return String.format("%5d. %s, %s", AEM, lastName, firstName);
   }   }
-     +   
-  Comparator<Student> lexicographicCmp = new Comparator<Student>() {+  // First anonymous comparator class 
 +  static Comparator<Student> lexicographicCmp = new Comparator<Student>() {
     public int compare(Student st1, Student st2) {     public int compare(Student st1, Student st2) {
       int cmp = st1.lastName.compareTo(st2.lastName);       int cmp = st1.lastName.compareTo(st2.lastName);
Line 55: Line 43:
         cmp = st1.AEM - st2.AEM;         cmp = st1.AEM - st2.AEM;
       return cmp;       return cmp;
-    } 
-    public boolean equals(Object o) { 
-      if(o instanceof Student) { 
-        Student st = (Student) o; 
-        if(firstName.equals(st.firstName) && lastName.equals(st.lastName) && AEM == st.AEM) 
-          return true; 
-      } 
-      return false; 
     }     }
   };   };
  
 +  public static void sortLexicographically(List<Student> students) {    
 +    Collections.sort(students, Student.lexicographicCmp);
 +  }
 +  
 +  public static void sortByAEM(List<Student> students) {
 +    // Second anonymous comparator class
 +    Collections.sort(students, new Comparator<Student>() {
 +        public int compare(Student st1, Student st2) {
 +          int cmp = st1.AEM - st2.AEM;
 +          if(cmp==0)
 +            cmp = st1.lastName.compareTo(st2.lastName);            
 +          if(cmp==0)
 +            cmp = st1.firstName.compareTo(st2.firstName);
 +          return cmp;
 +        }
 +      }
 +    );
 +  }
 +}
 +</code>
 +
 +Στη μέθοδο **//main//** διαβάζουμε από το αρχείο **students.txt** και καταχωρούμε το περιεχόμενο του σε μία λίστα (**ArrayList<Student>**). Στη συνέχεια εκτυπώνουμε τα στοιχεία της λίστας
 +  * με τη σειρά που τα διαβάσαμε
 +  * με λεξικογραφική σειρά.
 +  * με βάση το ΑΕΜ
 +
 +<code txt students.txt>
 +4596 Super Man
 +5819 Peter Pan
 +1694 Susan Brown
 +7895 Lena Smith
 +3256 Oscar Gonzales
 +1243 Edgar Wallace
 +3265 Kate Gordon
 +4377 Leda Evans
 +1118 David Lerroy
 +8744 Amelia Dray
 +</code>
 +
 +<code java SortListOfStudents.java>
 +import java.io.*;
 +import java.util.*;
 +
 +public class SortListOfStudents {
 +  
   public static void readFromFile(List<Student> students, File f) {       public static void readFromFile(List<Student> students, File f) {    
     try(Scanner sc = new Scanner(f)) {     try(Scanner sc = new Scanner(f)) {
Line 80: Line 105:
       System.exit(-1);       System.exit(-1);
     }     }
-  } 
-   
-  public void sortLexicographically(List<Student> students) {     
-    Collections.sort(students, lexicographicCmp); 
-  } 
-     
-  public void sortByAEM(List<Student> students) { 
-    Collections.sort(students, new Comparator<Student>() { 
-        public int compare(Student st1, Student st2) { 
-          int cmp = cmp = st1.AEM - st2.AEM; 
-          if(cmp==0) 
-            cmp = st1.lastName.compareTo(st2.lastName);             
-          if(cmp==0) 
-            cmp = st1.firstName.compareTo(st2.firstName); 
-          return cmp; 
-        } 
-        public boolean equals(Object o) { 
-          if(o instanceof Student) { 
-            Student st = (Student) o; 
-            if(firstName.equals(st.firstName) && lastName.equals(st.lastName) && AEM == st.AEM) 
-              return true; 
-          } 
-          return false; 
-        } 
-      } 
-    ); 
   }   }
      
   public static String toString(List<Student> students) {   public static String toString(List<Student> students) {
-    StringBuffer str = new StringBuffer();+    StringBuilder str = new StringBuilder();
     for(Student st : students)      for(Student st : students) 
       str.append(st+"\n");       str.append(st+"\n");
Line 125: Line 124:
     System.out.println(" --- Init Ordering ---\n");     System.out.println(" --- Init Ordering ---\n");
     System.out.println(toString(students));     System.out.println(toString(students));
-    students.get(0).sortLexicographically(students);+    Student.sortLexicographically(students);
     System.out.println(" --- Lexicographic Ordering ---\n");     System.out.println(" --- Lexicographic Ordering ---\n");
     System.out.println(toString(students));     System.out.println(toString(students));
-    students.get(0).sortByAEM(students);+    Student.sortByAEM(students);
     System.out.println(" --- AEM Ordering ---\n");     System.out.println(" --- AEM Ordering ---\n");
     System.out.println(toString(students));     System.out.println(toString(students));
   }   }
-     
 } }
 </code> </code>
 +
  
 ===== Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως επέκταση υφιστάμενης κλάσης ===== ===== Παράδειγμα - Ανώνυμη εμφωλευμένη κλάση ως επέκταση υφιστάμενης κλάσης =====
  
 +Δείτε το προηγούμενο παράδειγμα παραλλαγμένο ως εξής. Αρχικά φτιάχνουμε την εσωτερική //abstract// κλάση **BasicComparator** που περιέχει μόνο την μέθοδο //equals// του //interface// [[https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html|java.util.Comparator]]. Στη συνέχεια ορίζουμε δύο ανώνυμες εμφωλευμένες κλάσεις (όπως στο προηγούμενο παράδειγμα), οι οποίες δεν υλοποιούν το //interface// java.util.Comparator, αλλά την εσωτερική //abstract// κλάση **BasicComparator**.
  
-Παρακάτω δίνεται ένα άλλο παράδειγμα, όπου η ανώνυμη κλάση επεκτείνει μία υφιστάμενη κλάση αντί για ένα //inteface//.+<code java Student.java> 
 +import java.util.Comparator; 
 +import java.util.*; 
 +import java.io.*;
  
-<code java HelloWorldAnonymousClasses.java> +class Student { 
-public class HelloWorldAnonymousClasses {+  String firstName; 
 +  String lastName; 
 +  int AEM; 
 + 
 +  public Student(int AEM, String firstName, String lastName) { 
 +    this.firstName = firstName; 
 +    this.lastName = lastName; 
 +    this.AEM = AEM; 
 +  } 
 +     
 +  public String toString() { 
 +    return String.format("%5d. %s, %s", AEM, lastName, firstName); 
 +  }
      
-  interface HelloWorld { +  static abstract class BasicComparator implements Comparator<Student> {
-    public void greet(); +
-    public void greetSomeone(String someone);+
   }   }
 +    
 +  static Comparator<Student> lexicographicCmp = new BasicComparator() {
 +    public int compare(Student st1, Student st2) {
 +      int cmp = st1.lastName.compareTo(st2.lastName);
 +      if(cmp==0)
 +        cmp = st1.firstName.compareTo(st2.firstName);
 +      if(cmp==0)
 +        cmp = st1.AEM - st2.AEM;
 +      return cmp;
 +    }    
 +  };
      
-  public static void sayHello() {+  public static void sortLexicographically(List<Student> students) {     
 +    Collections.sort(students, lexicographicCmp); 
 +  }
          
-    class EnglishGreeting implements HelloWorld +  public static void sortByAEM(List<Student> students) 
-      String name = "world"; +    Collections.sort(students, new BasicComparator() { 
-      public void greet() { +        public int compare(Student st1, Student st2) { 
-        greetSomeone("world");+          int cmp = cmp = st1.AEM - st2.AEM; 
 +          if(cmp==0) 
 +            cmp = st1.lastName.compareTo(st2.lastName);             
 +          if(cmp==0) 
 +            cmp = st1.firstName.compareTo(st2.firstName); 
 +          return cmp; 
 +        }        
       }       }
-      public void greetSomeone(String someone) { +    ); 
-        name = someone; +  } 
-        System.out.println("Hello " + name); +
-      } +
-    } +
-     +
-    HelloWorld englishGreeting = new EnglishGreeting(); +
-     +
-    HelloWorld frenchGreeting = new HelloWorld() { +
-      String name = "tout le monde"; +
-      public void greet() { +
-        greetSomeone("tout le monde"); +
-      } +
-      public void greetSomeone(String someone) { +
-        name = someone; +
-        System.out.println("Salut " + name); +
-      } +
-    }; +
-     +
-    HelloWorld spanishGreeting = new EnglishGreeting() { +
-      String name = "mundo"; +
-      public void greet() { +
-        greetSomeone("mundo"); +
-      } +
-      public void greetSomeone(String someone) { +
-        name = someone; +
-        System.out.println("Hola, " + name); +
-      } +
-    }; +
-    englishGreeting.greet(); +
-    frenchGreeting.greetSomeone("Fred"); +
-    spanishGreeting.greet(); +
-  } +
- +
-  public static void main(String... args) {     +
-    HelloWorldAnonymousClasses.sayHello(); +
-  }      +
 } }
 </code> </code>
- 
-<WRAP tip 80% center round> 
-Παρατηρήστε ότι η μεταβλητή //frenchGreeting// προκύπτει από μία κλάση που υλοποιεί το inteface //HelloWorld// η μεταβλητή //spanishGreeting// προκύπτει ως επέκταση της κλάση //EnglishGreeting//. 
-</WRAP> 
  
 ===== Πρόσβαση στις τοπικές μεταβλητές και στις μεταβλητές της εξωτερικής κλάσης ===== ===== Πρόσβαση στις τοπικές μεταβλητές και στις μεταβλητές της εξωτερικής κλάσης =====
  
-Σε αναλογία με τις [[java:local_inner_classes|τοπικές εμφωλευμένες κλάσεις]] οι ανώνυμες κλάσεις έχουν τις ίδιες δυνατότητες πρόσβασης στις τοπικές μεταβλήτές της μεθόδου στην οποία ορίζονται:+Σε αναλογία με τις [[java:local_inner_classes|τοπικές εμφωλευμένες κλάσεις]] οι ανώνυμες κλάσεις έχουν τις ίδιες δυνατότητες πρόσβασης στις τοπικές μεταβλητές της μεθόδου στην οποία ορίζονται:
   * Η ανώνυμη κλάση έχει πρόσβαση στις μεταβλητές της εξωτερικής κλάσης.   * Η ανώνυμη κλάση έχει πρόσβαση στις μεταβλητές της εξωτερικής κλάσης.
-  * Η ανώνυμη κλάση δεν μπορεί να έχει πρόσβαση σε τοπικές μεταβλητές της μεθόδου στην οποία ορίζονται αν αυτές δεν έχουν δηλωθεί ως //final//.+  * Η ανώνυμη κλάση δεν μπορεί να έχει πρόσβαση σε τοπικές μεταβλητές της μεθόδου στην οποία ορίζεται αν αυτές δεν έχουν δηλωθεί ως //final//.
   * Όπως σε όλες τις μη στατικές εμφωλευμένες κλάσεις ο ορισμός του ίδιου τύπου δεδομένων στην εσωτερική και την εξωτερική κλάση "//κρύβει//" τον συγκεκριμένο τύπο δεδομένων από την εξωτερική κλάση.   * Όπως σε όλες τις μη στατικές εμφωλευμένες κλάσεις ο ορισμός του ίδιου τύπου δεδομένων στην εσωτερική και την εξωτερική κλάση "//κρύβει//" τον συγκεκριμένο τύπο δεδομένων από την εξωτερική κλάση.
-  * Δεν μπορείτε να ορίσετε στατικές μεταβλητές ή μεθόδους μέσα σε μία ανώνυμη κλάση.+  * __Δεν μπορείτε__ να ορίσετε στατικές μεταβλητές ή μεθόδους μέσα σε μία ανώνυμη κλάση.
  
 Σε μία ανώνυμη κλάση μπορείτε να ορίσετε τα εξής: Σε μία ανώνυμη κλάση μπορείτε να ορίσετε τα εξής:
   * Πεδία   * Πεδία
-  * Επιπλέον μεθόδους που δεν ορίζονται στη interface ή στην κλάση που επεκτείνει. +  * Επιπλέον μεθόδους που δεν ορίζονται στο interface ή στην κλάση που επεκτείνεται.
-  * Μεθόδους ή block αρχικοποίησης πεδίων της κλάσης.+
   * Τοπικές κλάσεις που ανήκουν στη ανώνυμη κλάση.   * Τοπικές κλάσεις που ανήκουν στη ανώνυμη κλάση.
   * **ΔΕΝ** μπορείτε και __δεν έχει νόημα__ να ορίσετε κατασκευαστές μέσα σε μία ανώνυμη κλάση.   * **ΔΕΝ** μπορείτε και __δεν έχει νόημα__ να ορίσετε κατασκευαστές μέσα σε μία ανώνυμη κλάση.
  
 | Προηγούμενο : [[ :java:local_inner_classes | Τοπικές εμφωλευμένες κλάσεις   ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο: [[ :java:static_nested_classes | Στατικές εμφωλευμένες κλάσεις  ]]  | | Προηγούμενο : [[ :java:local_inner_classes | Τοπικές εμφωλευμένες κλάσεις   ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο: [[ :java:static_nested_classes | Στατικές εμφωλευμένες κλάσεις  ]]  |
java/anon_inner_classes.1521624760.txt.gz · Last modified: 2018/03/21 09:32 by gthanos