This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
java:generic_bounded_types [2015/03/15 21:10] gthanos |
java:generic_bounded_types [2015/03/15 21:41] gthanos [Σχέσεις κληρονομικότητας φραγμένων παραμετρικών τύπων δεδομένων] |
||
---|---|---|---|
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''). |
- | 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?300 }} | + | Στην παραπάνω δήλωση ο τύπος δεδομένων της παραμετρικής κλάσης ''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>''. Αν θέλουμε να γράψουμε μία αρκετά γενική μέθοδο λίστας που να τυπώνει λίστες οποιουδήποτε αντικειμένου αρκεί να γράψετε το παρακάτω | ||
+ | |||
+ | <code java> | ||
+ | public static void printList(List<?> list) { | ||
+ | for (Object elem: list) | ||
+ | System.out.print(elem + " "); | ||
+ | System.out.println(); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Σχέσεις κληρονομικότητας φραγμένων παραμετρικών τύπων δεδομένων ===== | ||
+ | |||
+ | Όπως είδαμε οι τύποι ''List<Integer>'' και ''List<String>'' δεν διέπονται από καμία σχέση κληρονομικότητας. Ο κοινός πατέρας και τον δύο λιστών είναι η κλάση ''List<?>'', όπως φαίνεται παρακάτω | ||
+ | {{ :java:generics_inheritance3.png?500 |}} | ||
+ | |||
+ | |||
+ | Γενικότερα προκειμένου να δημιουργήσουμε σχέσεις κληρονομικότητας μεταξύ παραμετρικών τύπων δεδομένων, ο μόνος τρόπος για να το κάνουμε είναι να χρησιμοποιήσουμε φραγμένους παραμετρικούς τύπους, όπως παρακάτω | ||
+ | <code java> | ||
+ | List<? extends Integer> intList = new ArrayList<>(); | ||
+ | List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number> | ||
+ | </code> | ||
+ | |||
+ | Το παρακάτω σχήμα εξηγεί τις σχέσεις κληρονομικότητας που διέπουν (άνω και κάτω) φραγμένους τύπους δεδομένων (Λίστες). | ||
+ | {{ :java:generics_inheritance4.png?500 |}} | ||
+ | |||
+ | |||
+ |