java:generic_bounded_types

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:generic_bounded_types [2015/03/15 21:16]
gthanos
java:generic_bounded_types [2016/02/26 11:15] (current)
Line 1: Line 1:
-====== ​Κληρονομικότητα ​παραμετρικών τύπων δεδομένων ======+====== ​Φραγμένοι παραμετρικοί τύπων δεδομένων ====== 
 + 
 +===== Άνω φραγμένοι παραμετρικοί τύποι (Upper Bounded Wildcards) ​=====
  
 <code java> <code java>
-public void boxTest(Box<​Number> ​n) { /* ... */ }  //line 1+public ​static ​void process(List<? extends ​Number> ​list) { /* ... */ } 
 +</code>
  
-Box<Number> box = new Box<Number>();  //line 3 +Στην παραπάνω δήλωση ο τύπος δεδομένων της παραμετρικής κλάσης ''​List''​ μπορεί να είναι η κλάση ''​Number''​ η οποιαδήποτε υποκλάση της ''​Number'' ​(π.χ ''​Integer'',​ ''​Double'',​ ''​Float''​).
-box.add(new ​Integer(10));             //​line 4 +
-box.add(new Double(10.1)); ​           //line 5+
  
-Box<​Double>​ doubleBox ​new Box<​Double>​(); // line 7 +===== Κάτω φραγμένοι παραμετρικοί τύποι ​(Lower Bounded Wildcards=====
-doubleBox.add(new Double(10.1)); ​          // line 8+
  
-box.boxTest(doubleBox); // μπορούμε να γράψουμε?​+<code java> 
 +public static void addNumbers(List<?​ super Integer> list) { 
 +    for (int i = 1; i <= 10; i++) { 
 +        list.add(i); 
 +    } 
 +}
 </​code>​ </​code>​
-Ο παραπάνω κώδικας είναι σωστός στις γραμμές 3-5 διότι οι κλάσεις ''​Integer''​ και ''​Double''​ είναι υποκλάσεις της κλάσης ''​Number''​. Δεν ισχύει όμως το ίδιο για την γραμμή 8 καθώς η κλάση ''​Box<​Double>''​ **__δεν είναι__** υποκλάση της κλάσης ''​Box<​Number>'',​ όπως δείχνει το παρακάτω σχήμα. 
-{{  :​java:​generics_inheritance1.png?​500 ​ }}  
  
-Μπορείτε να υλοποιήσετε παραμετρικούς τύπους δεδομένων ​που κληρονομούν από άλλους παραμετρικούς τύπους δεδομένων. Για παράδειγμα από την standard βιβλιοθήκη της Java μπορείτε να δείτε ότι ο τύπος ​''​ArrayList<​E>​'' ​υλοποιεί το interface ​''​List<​E>​''​. ​Το interface ​''​List<​E>​'' ​με την σειρά του επεκτείνει το interface ''​Collection<​E>''​. Έτσι μπορεί να οριστεί η παρακάτω ​ιεραρχία +Στην παραπάνω δήλωση ο τύπος δεδομένων ​της παραμετρικής κλάσης ''​List'' ​μπορεί να είναι η κλάση ​''​Integer'' ​ή οποιαδήποτε υπερ-κλάση ​της ''​Integer'' ​.χ ''​Number''​). 
-<​code>​ + 
-  ​Collection<E>                           ​Collection<​String+===== Μη φραγμένοι παραμετρικοί τύποι (Unbounded Wildcards) ===== 
-      ​| ​                                         | + 
-      ​v ​                                         v +Ας εξετάσουμε τους μη φραγμένους παραμετρικούς τύπους μέσα το παρακάτω ​παράδειγμα. 
-    ​List<​E> ​              π.χ             ​List<​String> ​ +<​code ​java
-      ​| ​                                         | +public static void printList(List<Objectlist) { 
-      v                                          v +    for (Object elem : list) 
-  ArrayList<​E> ​                             ArrayList<​String>​+        ​System.out.println(elem + " "); 
 +    ​System.out.println(); 
 +}
 </​code>​ </​code>​
 +
 +Ο παραπάνω κώδικας τυπώνει αντικείμενα από μία λίστα αντικειμένων τύπου ''​Οbject''​. Λόγω των περιορισμών στην κληρονομικότητα που είδαμε προηγούμενα ο ίδιος κώδικας δεν μπορεί να χρησιμοποιηθεί για να τυπώσει αντικείμενα τύπου ''​List<​String>''​ ή ''​List<​Integer>''​ καθώς δεν μπορούμε να τοποθετήσουμε στην παράμετρο ''​List<​Object>''​ ένα αντικείμενο άλλης κλάσης. Κατά συνέπεια θα χρειαστούμε ένα άλλο τρόπο γραφής της συγκεκριμένης κλάσης,​ ώστε να απαντά στην γενικότητα.
 +
 +Αν θέλουμε να γράψουμε μία αρκετά γενική μέθοδο λίστας που να τυπώνει λίστες οποιουδήποτε αντικειμένου αρκεί να γράψετε το παρακάτω
 +
 +<code java>
 +public static void printList(List<?>​ list) {
 +    for (Object elem: list)
 +        System.out.print(elem + " ");
 +    System.out.println();​
 +}
 +</​code>​
 +
 +Αντίστοιχα,​ αν θέλουμε να γράψουμε μία μέθοδο που να τυπώνει μόνο αριθμούς (υποκλάσεις της //​abstract//​ κλάσης ''​Number''​) τότε αρκεί να γράψουμε το παρακάτω
 +
 +<code java>
 +public static void printΝumbers(List<?​ extends Number> list) {
 +    for (Number num: list)
 +        System.out.print(num + " ");
 +    System.out.println();​
 +}
 +</​code>​
 +
 +===== Σχέσεις κληρονομικότητας φραγμένων παραμετρικών τύπων δεδομένων =====
 +
 +Όπως είδαμε οι τύποι ''​List<​Integer>''​ και ''​List<​String>''​ δεν διέπονται από καμία σχέση κληρονομικότητας. Ο κοινός πατέρας και τον δύο λιστών είναι η κλάση ''​List<?>'',​ όπως φαίνεται παρακάτω
 +{{ :​java:​generics_inheritance3.png?​500 |}}
 +
 +Γενικότερα,​ σχέσεις κληρονομικότητας μεταξύ φραγμένων τύπων ισχύουν με κριτήρια κατά πόσο μπορούμε να αντικαταστήσουμε ένα τύπο δεδομένων με έναν άλλο τύπο δεδομένων. Δείτε τα παρακάτω παραδείγματα κληρονομικότητας
 +<code java>
 +      List<?>​
 +         |
 +         v
 + ​List<?​ extends Number>
 +         |
 +         v
 + ​List<?​ extends Integer>
 +         |
 +         v
 +    List<​Integer>​
 +</​code>​
 +
 +Αντίστοιχα ισχύουν
 +<code java>
 +      List<?>​
 +         |
 +         v
 + ​List<?​ super Integer>
 +         |
 +         v
 + ​List<?​ super Number>
 +         |
 +         v
 +    List<​Number>​
 +</​code>​
 +
 +Ανάλογα ισχύουν και τα παρακάτω
 +<code java>
 +              List<? extends Number> ​                                  ​List<?​ super Integer>
 +                        |                         ​και ​                          |
 +       ​------------------------------------ ​                    ​------------------------------------
 +       ​| ​                                 |                     ​| ​                                 |
 +       ​v ​                                 v                     ​v ​                                 v
 +   ​List<​Number> ​                    ​List<​Integer> ​          ​List<​Number> ​                    ​List<​Integer>​
 +</​code>​
 +
 +Δοκιμάστε να μεταγλωττίσετε τα παρακάτω παραδείγματα κώδικα για να επιβεβαιώσετε τα παραπάνω.
 +<code java>
 +List<? extends Νumber> numList = new ArrayList<>​();​
 +List<?> ​ objectList = numList;  ​
 +</​code>​
 +<code java>
 +List<? extends Integer> intList = new ArrayList<>​();​
 +List<? extends Number> ​ numList = intList;  ​
 +</​code>​
 +<code java>
 +List<​Integer>​ intList = new ArrayList<>​();​
 +List<? extends Integer> extendedIntList = intList;  ​
 +</​code>​
 +
 +Ανάλογα
 +<code java>
 +List<? super Integer> intList = new ArrayList<>​();​
 +List<?>​ objectList = intList;  ​
 +</​code>​
 +<code java>
 +List<? super Number> numList = new ArrayList<>​();​
 +List<? super Integer> inList = numList;  ​
 +</​code>​
 +<code java>
 +List<​Number>​ numList = new ArrayList<>​();​
 +List<? super Number> extendedNumList = numList; ​
 +</​code>​
 +
 +
 +
 +Το παρακάτω σχήμα εξηγεί τις σχέσεις κληρονομικότητας που διέπουν (άνω και κάτω) φραγμένους τύπους δεδομένων για τον παραμετρικό τύπο δεδομένων της λίστας.
 +{{ :​java:​generics_inheritance4.png?​500 |}}
 +
 +
 +
 +
java/generic_bounded_types.1426454194.txt.gz · Last modified: 2016/02/26 11:15 (external edit)