This shows you the differences between two versions of the page.
java:generic_bounded_types [2015/03/19 16:55] gthanos [Σχέσεις κληρονομικότητας φραγμένων παραμετρικών τύπων δεδομένων] |
java:generic_bounded_types [2016/02/26 11:15] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Φραγμένοι παραμετρικοί τύπων δεδομένων ====== | ||
- | |||
- | ===== Άνω φραγμένοι παραμετρικοί τύποι (Upper Bounded Wildcards) ===== | ||
- | |||
- | <code java> | ||
- | public static void process(List<? extends Number> list) { /* ... */ } | ||
- | </code> | ||
- | |||
- | Στην παραπάνω δήλωση ο τύπος δεδομένων της παραμετρικής κλάσης ''List'' μπορεί να είναι η κλάση ''Number'' η οποιαδήποτε υποκλάση της ''Number'' (π.χ ''Integer'', ''Double'', ''Float''). | ||
- | |||
- | ===== Κάτω φραγμένοι παραμετρικοί τύποι (Lower Bounded Wildcards) ===== | ||
- | |||
- | <code java> | ||
- | public static void addNumbers(List<? super Integer> list) { | ||
- | for (int i = 1; i <= 10; i++) { | ||
- | list.add(i); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | |||
- | Στην παραπάνω δήλωση ο τύπος δεδομένων της παραμετρικής κλάσης ''List'' μπορεί να είναι η κλάση ''Integer'' ή οποιαδήποτε υπερ-κλάση της ''Integer'' (π.χ ''Number''). | ||
- | |||
- | ===== Μη φραγμένοι παραμετρικοί τύποι (Unbounded Wildcards) ===== | ||
- | |||
- | Ας εξετάσουμε τους μη φραγμένους παραμετρικούς τύπους μέσα το παρακάτω παράδειγμα. | ||
- | <code java> | ||
- | public static void printList(List<Object> list) { | ||
- | for (Object elem : list) | ||
- | System.out.println(elem + " "); | ||
- | System.out.println(); | ||
- | } | ||
- | </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 |}} | ||
- | |||
- | |||
- | |||