Προγράμματα με δομή Κληρονομικότητας
Η μέθοδος print της εφαρμογής DoME Η μέθοδος print στην κλάση Item τυπώνει: title: A Swingin Affair (64 mins) my favorite Sinatra album title: O Brother, Where Art Thou? (106 mins) title: O Brother, Where Art Thou? (106 mins) The Coen brothers best movie!
Η μέθοδος print της εφαρμογής DoME Θα έπρεπε να μπορούμε να τυπώνουμε όπως στην εφαρμογή χωρίς κληρονομικότητα όλες τις πληροφορίες: CD: DVD: A Swingin Affair (64 mins) Frank Sinatra tracks: 16 my favorite Sinatra album O Brother, Where Art Thou? (106 mins) Joel & Ethan Coen The Coen brothers best movie! Η κληρονομικότητα είναι μονόδρομος: η κλάση CD κληρονομεί τα πεδία της Item, αλλά η Item δε γνωρίζει τίποτα για τα πεδία στις υποκλάσεις της.
Στατικοί και δυναμικοί τύποι Αν προσπαθούσαμε να μεταφέρουμε μ τη ημέθοδο print από την κλάση Item στις υποκλάσεις, διαπιστώνουμε κάποια προβλήματα: το έργο δε μεταγλωττίζεται. έχουμε σφάλματα στις κλάσεις CD και DVD γιατί δε μπορούμε να προσπελάσουμε τα πεδία της υπερκλάσης προκύπτει σφάλμα στην κλάση Database γιατί δε μπορεί να βρει τη μέθοδο print for(item item : items) for(item item : items) item.print(); System.out.println();
Στατικοί και δυναμικοί τύποι Ο δηλωμένος τύπος της ηςμεταβλητής λέγεται στατικός τύπος, γιατί δηλώνεται στον πηγαίο κώδικα τη στατική αναπαράσταση του προγράμματος. Ο τύπος του αντικειμένου που αποθηκεύεται σε μια μεταβλητή ονομάζεται δυναμικός τύπος, γιατί εξαρτάται από αναθέσεις που γίνονται κατά το χρόνο εκτέλεσης τη δυναμική συμπεριφορά ενός προγράμματος. Τη στιγμή της κλήσης item.print(); ο στατικός τύπος της item είναι Item, ενώ ο δυναμικός τύπος ο στατικός τύπος της item είναι Item, ενώ ο δυναμικός τύπος είναι είτε CD είτε DVD.
Στατικοί και δυναμικοί τύποι Για τον έλεγχο τύπων ο μεταγλωττιστής χρησιμοποιεί τους στατικούς τύπους. Ο δυναμικός τύπος συχνά προσδιορίζεται μόνο κατά το χρόνο εκτέλεσης. Για να λειτουργήσει η κλήση, item.print(); η κλάση Item πρέπει να έχει μια μέθοδο print.
Υποσκέλιση (overrriding)
Υποσκέλιση (overrriding) public class Item.......... public void print() System.out.print(title + " (" + playingtime + " mins)"); if(gotit) System.out.println("*"); else System.out.println(); public class CD extends Item System.out.println(" " + comment);......... public void print() System.out.println(" " + artist); Τα αντικείμενα της υποκλάσεις System.out.println(" tracks: " + numberoftracks); έχουν δύο μεθόδους με το ίδιο όνομα. Ποια από τις δύο θα εκτελεστεί όταν καλέσουμε τη μέθοδο print;
Δυναμική αναζήτηση μεθόδων Ο έλεγχος τύπων χρησιμοποιεί το στατικό τύπο,, αλλά κατά το χρόνο εκτέλεσης εκτελούνται οι μέθοδοι που καθορίζει ο δυναμικός τύπος. Αυτή η διαδικασία δ είναι γνωστή ως αναζήτηση μεθόδου (method lookup ή method dispatch).
Κλήση της super σε μεθόδους Παράδειγμα public void print() super.print( ); System.out.println(" " + artist); System.out.println(" tracks: " + numberoftracks); Σε αντίθεση με τις κλήσεις της super στους κατασκευαστές, το όνομα της μεθόδου υπερκλάσης πρέπει να δηλώνεται ρητά. Αντίθετα με τον κανόνα για κλήσεις της super στους κατασκευαστές, η κλήση της super σε μεθόδους μπορεί να γίνει οπουδήποτε μέσα στη μέθοδο. Δε χρειάζεται να είναι η πρώτη εντολή. Σε αντίθεση με τις κλήσεις της super στους κατασκευαστές, δεν παράγεται αυτόματα και δεν απαιτείται η κλήση της super είναι εντελώς προαιρετική.
Πολυμορφισμός μεθόδων Οι κλήσεις ςμεθόδων στη Java είναι πολυμορφικές. Η ίδια κλήση μεθόδου μπορεί σε διαφορετικές στιγμές να ενεργοποιεί διαφορετικές μεθόδους, ανάλογα με το δυναμικό τύπο της μεταβλητής που χρησιμοποιείται για την κλήση αυτή. Παράδειγμα Η εντολή item.print( ); μπορεί να ενεργοποιεί τη μέθοδο print της κλάσης CD κάποια στιγμή, και τη μέθοδο print της κλάσης DVD κάποια άλλη στιγμή, ανάλογα με το δυναμικό τύπο της item.
Μέθοδοι της κλάσης Object: tostring Ο σκοπός της ηςμεθόδου tostring είναι ηδημιουργία μιας αλφαριθμητικής αναπαράστασης ενός αντικειμένου. Προκαθορισμένη υλοποίηση της μεθόδου tostring στην κλάση Object Παράδειγμα: κλήση τη μεθόδου tostring για ένα αντικείμενο DVD DVD@6acdd1 ηεπιστρεφόμενη τιμή απλώς παρουσιάζει το όνομα κλάσης του αντικειμένου και έναν αριθμό, που αντιστοιχεί στη διεύθυνση μνήμης στην οποία αποθηκεύεται το αντικείμενο.
Μέθοδοι της κλάσης Object: tostring Για να είναι πιο χρήσιμη αυτή η μέθοδος συνήθως την υποσκελίζουμε στις κλάσεις μας public class Item....... public String tostring() String line1= title + " (" + playingtime + " mins)"; if(gotit) return line1 + *\n + + comment + \n ; else return line1 + \n + + comment + \n ; public void print() System.out.println(toString());
Μέθοδοι της κλάσης Object: tostring public class CD extends Item................ public String tostring() return super.tostring() + + artist + \n tracks: + numberoftracks + \n ; public void print() System.out.println(toString());
Μέθοδοι της κλάσης Object: tostring Με την tostring απλά διοχετεύουμε κείμενο και το πώς πρόκειται να χρησιμοποιηθεί αυτό το κείμενο εξαρτάται από τη μέθοδο που καλεί την tostring (π.χ. να αποθηκευτεί σε ένα αρχείο). Η εντολή που χρησιμοποιείται για την εκτύπωση είναι: System.out.println(item.toString()); αλλά μπορούμε επίσης να γράψουμε System.out.println(item);
Μέθοδοι της κλάσης Object: tostring Μπορούμε να αφαιρέσουμε εντελώς τις ςμεθόδους ςprint από τις κλάσεις: αν η παράμετρος σε μία System.out.println δεν είναι κάποιο αλφαριθμητικό αντικείμενο, τότε η μέθοδος καλεί αυτόματα τη μέθοδο tostring του αντικειμένου! public class Database........ public void list() for(item item : items) System.out.println(item);