Πανεπιστήμιο Πειραιά Τμήμα Ψηφιακών Συστημάτων Αντικειμενοστρεφής Προγραμματισμός 24/4/2017 Δρ. Ανδριάνα Πρέντζα Αναπληρώτρια Καθηγήτρια aprentza@unipi.gr
Υπερφόρτωση μεθόδων Υπερφόρτωση μεθόδων Πολλαπλές μέθοδοι με το ίδιο όνομα, αλλά διαφορετικό τύπο, αριθμό ή σειρά παραμέτρων στη λίστα παραμέτρων τους Ο μεταγλωττιστής αποφασίζει ποια μέθοδος καλείται συνταιριάζοντας τη λίστα παραμέτρων στην κλήση της μεθόδου με μίας από τις λίστες παραμέτρων των υπερφορτωμένων μεθόδων Το όνομα μαζί με τον αριθμό, τύπο και σειρά παραμέτρων μιας μεθόδου αποτελούν την υπογραφή της Διαφορές στον τύπο επιστροφής είναι άσχετες με την υπερφόρτωση μεθόδων Οι υπερφορτωμένες μέθοδοι μπορούν να έχουν διαφορετικούς τύπους επιστροφής Μέθοδοι με διαφορετικούς τύπους επιστροφής, αλλά με την ίδια υπογραφή, προκαλούν compilation error
1 // Fig. 6.13: MethodOverload.java 2 // Overloaded method declarations. 3 4 public class MethodOverload 5 { 6 // test overloaded square methods 7 public void testoverloadedmethods() Υπερφόρτωση μεθόδων 8 { 9 System.out.printf( "Square of integer 7 is %d\n", square(7) ); 10 System.out.printf( "Square of double 7.5 is %f\n", square(7.5) ); 11 } // end method testoverloadedmethods 12 13 // square method with int argument 14 public int square(int intvalue) 15 { 16 System.out.printf("\nCalled square with int argument: %d\n", 17 intvalue); 18 return intvalue * intvalue; 19 } // end method square with int argument 20 21 // square method with double argument 22 public double square(double doublevalue) 23 { 24 System.out.printf("\nCalled square with double argument: %f\n", 25 doublevalue); 26 return doublevalue * doublevalue; 27 } // end method square with double argument 28 } // end class MethodOverload Σωστά καλεί τη μέθοδο square of int Σωστά καλεί τη μέθοδο square of double Δήλωση της μεθόδου square of int Δήλωση της μεθόδου square of double
1 // Fig. 6.14: MethodOverloadTest.java 2 // Application to test class MethodOverload. 3 4 public class MethodOverloadTest 5 { Υπερφόρτωση μεθόδων 6 public static void main( String args[] ) 7 { 8 MethodOverload methodoverload = new MethodOverload(); 9 methodoverload.testoverloadedmethods(); 10 } // end main 11 } // end class MethodOverloadTest Called square with int argument: 7 Square of integer 7 is 49 Called square with double argument: 7.500000 Square of double 7.5 is 56.250000 Οι τιμές κινητής υποδιαστολής προβάλλονται με ακρίβεια 6 ψηφίων αν δεν καθορίζεται ακρίβεια στο προσδιοριστικό μορφής
1 // Fig. 6.15: MethodOverloadError.java 2 // Overloaded methods with identical signatures 3 // cause compilation errors, even if return types are different. 4 5 public class MethodOverloadError 6 { Υπερφόρτωση μεθόδων 7 // declaration of method square with int argument 8 public int square(int x) 9 { 10 return x * x; 11 } 12 13 // second declaration of method square with int argument Ίδιες υπογραφές μεθόδων 14 // causes compilation error even though return types are different 15 public double square(int y) 16 { 17 return y * y; 18 } 19 } // end class MethodOverloadError MethodOverloadError.java:15: square(int) is already defined in MethodOverloadError public double square(int y) ^ Compilation error 1 error
Περισσότερα για constructors!
Προεπιλεγμένοι (Default) Κατασκευαστές και Κατασκευαστές χωρίς ορίσματα Κάθε κλάση πρέπει να έχει τουλάχιστον έναν κατασκευαστή Αν δεν δηλωθούν κατασκευαστές, ο compiler θα δημιουργήσει ένα προεπιλεγμένο κατασκευαστή Δεν παίρνει ορίσματα και αρχικοποιεί μεταβλητές στιγμιοτύπου στις αρχικές τους τιμές που προσδιορίζονται στη δήλωσή τους ή στις προεπιλεγμένες τιμές τους Οι προεπιλεγμένες τιμές είναι μηδενικές για πρωταρχικούς (primitive) αριθμητικούς τύπους, false για boolean τιμές και null για αναφορές (references) Αν δηλωθούν κατασκευαστές, η προεπιλεγμένη αρχικοποίηση αντικειμένων της κλάσης θα λάβει χώρα από έναν κατασκευαστή χωρίς ορίσματα (αν έχει δηλωθεί κάποιος)
Συνηθισμένο σφάλμα προγραμματισμού Αν μια κλάση έχει κατασκευαστές, μα κανείς από τους public κατασκευαστές δεν είναι κατασκευαστής χωρίς ορίσματα (no-argument), και ένα πρόγραμμα προσπαθεί να καλέσει έναν no-argument κατασκευαστή για να αρχικοποιήσει ένα αντικείμενο της κλάσης, συμβαίνει compilation error Ένας κατασκευαστής μπορεί να κληθεί χωρίς ορίσματα μόνο όταν η κλάση δεν έχει κάποιον κατασκευαστή (οπότε και καλείται ο προεπιλεγμένος κατασκευαστής) ή όταν η κλάση έχει έναν public κατασκευαστή χωρίς ορίσματα
Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές (συναρτήσεις δημιουργίας) Υπερφορτωμένοι κατασκευαστές Παρέχονται πολλαπλοί ορισμοί κατασκευαστών με διαφορετικές υπογραφές (διαφοροποίηση ως προς το πλήθος παραμέτρων, τύπους παραμέτρων και σειρά τύπων παραμέτρων) No-argument constructor Ένας κατασκευαστής που καλείται χωρίς ορίσματα Η αναφορά this μπορεί να χρησιμοποιηθεί για να καλέσει έναν άλλο κατασκευαστή Επιτρέπεται μόνο ως η πρώτη εντολή στο σώμα ενός κατασκευαστή!
Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 5 κατασκευαστές 4 από τους κατασκευαστές καλούν έναν 5 ο κατασκευαστή ο οποίος με τη σειρά του καλεί τη μέθοδο settime για να εξασφαλίσει ότι η τιμή που δόθηκε για την hour βρίσκεται στο εύρος 0 ως 23 και ότι οι τιμές για minute και second βρίσκονται στο εύρος 0 ως 59
1 // Fig. 8.5: Time2.java 2 // Time2 class declaration with overloaded constructors. 3 4 public class Time2 5 {...Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 6 private int hour; // 0-23 Κατασκευαστής χωρίς 7 private int minute; // 0-59 ορίσματα 8 private int second; // 0-59 9 10 // Time2 no-argument constructor: initializes each instance variable 11 // to zero; ensures that Time2 objects start in a consistent state 12 public Time2() 13 { 14 this(0, 0, 0); // invoke Time2 constructor with three arguments 15 } // end Time2 no-argument constructor 16 17 // Time2 constructor: hour supplied, minute and second defaulted to 0 18 public Time2(int h) 19 { 20 this(h, 0, 0); // invoke Time2 constructor with three arguments 21 } // end Time2 one-argument constructor 22 23 // Time2 constructor: hour and minute supplied, second defaulted to 0 24 public Time2(int h, int m) 25 { 26 this(h, m, 0); // invoke Time2 constructor with three arguments 27 } // end Time2 two-argument constructor 28 Κλήση κατασκευαστή τριών ορισμάτων
29 // Time2 constructor: hour, minute and second supplied 30 public Time2(int h, int m, int s) 31 { 32 settime(h, m, s); // invoke settime to validate time 33 } // end Time2 three-argument constructor...ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 34 35 // Time2 constructor: another Time2 object supplied 36 public Time2(Time2 time) 37 { 38 // invoke Time2 three-argument constructor 39 this(time.gethour(), time.getminute(), time.getsecond()); 40 } // end Time2 constructor with a Time2 object argument 41 42 // Set Methods 43 // set a new time value using universal time; ensure that 44 // the data remains consistent by setting invalid values to zero 45 public void settime(int h, int m, int s) 46 { 47 sethour(h); // set the hour 48 setminute(m); // set the minute 49 setsecond(s); // set the second 50 } // end method settime 51 Κλήση της μεθόδου settime Ο κατασκευαστής παίρνει ως παράμετρο μια αναφορά σε άλλο αντικείμενο Time2 Θα μπορούσαμε να προσπελάσουμε απευθείας τις μεταβλητές στιγμιοτύπου του αντικειμένου time
52 // validate and set hour 53 public void sethour(int h) 54 { 55 hour = ( ( h >= 0 && h < 24 )? h : 0 ); 56 } // end method sethour...ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 57 58 // validate and set minute 59 public void setminute(int m) 60 { 61 minute = ( ( m >= 0 && m < 60 )? m : 0 ); 62 } // end method setminute 63 64 // validate and set second 65 public void setsecond(int s) 66 { 67 second = ( ( s >= 0 && s < 60 )? s : 0 ); 68 } // end method setsecond 69 70 // Get Methods 71 // get hour value 72 public int gethour() 73 { 74 return hour; 75 } // end method gethour 76 Επικύρωση τιμών παραμέτρων πριν ανατεθούν στις μεταβλητές στιγμιοτύπου. Η έκφραση συνθηκών ελέγχει κάθε όρισμα για να καθορίσει αν η τιμή βρίσκεται σε καθορισμένη περιοχή. Οποιεσδήποτε τιμές εκτός περιοχής τίθενται σε μηδέν ως προεπιλογή, έτσι ώστε ένα αντικείμενο Time2 να έχει πάντα έγκυρα δεδομένα Ο τελεστής συνθηκών (?:) καθορίζει την τιμή της hour. Αν η hour είναι μεταξύ 0 και 24, καταχωρείται αυτή η τιμή στην hour, διαφορετικά καταχωρείται η τιμή 0
77 // get minute value 78 public int getminute() 79 { 80 return minute; 81 } // end method getminute...ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές Ο τελεστής συνθηκών (?:) καθορίζει την τιμή της hour στην ακολουθία χαρακτήρων αν η hour είναι 0 ή 12 (AM ή PM) η hour εμφανίζεται ως 12, διαφορετικά η ώρα εμφανίζεται ως μία τιμή μεταξύ 1-11 82 83 // get second value 84 public int getsecond() 85 { 86 return second; 87 } // end method getsecond 88 89 // convert to String in universal-time format (HH:MM:SS) 90 public String touniversalstring() 91 { 92 return String.format( 93 "%02d:%02d:%02d", gethour(), getminute(), getsecond() ); 94 } // end method touniversalstring 95 96 // convert to String in standard-time format (H:MM:SS AM or PM) 97 public String tostring() 98 { 99 return String.format( "%d:%02d:%02d %s", 100 ( (gethour() == 0 gethour() == 12)? 12 : gethour() % 12 ), 101 getminute(), getsecond(), ( gethour() < 12? "AM" : "PM" ) ); 102 } // end method tostring 103 } // end class Time2 Ο τελεστής συνθηκών (?:) καθορίζει αν θα επιστραφεί AM ή PM
Συνηθισμένο σφάλμα προγραμματισμού Είναι συντακτικό σφάλμα όταν η αναφορά this χρησιμοποιείται στο σώμα ενός κατασκευαστή για να καλέσει έναν άλλο κατασκευαστή της ίδιας κλάσης και περιέχεται σε εντολή που ΔΕΝ είναι η πρώτη εντολή στον κατασκευαστή Είναι επίσης συντακτικό σφάλμα όταν μια μέθοδος προσπαθεί να καλέσει έναν κατασκευαστή άμεσα μέσω της this Ο κατασκευαστής καλεί την settime για να αρχικοποιήσει τις μεταβλητές στιγμιοτύπου σε συνεπείς τιμές.
1 // Fig. 8.6: Time2Test.java 2 // Overloaded constructors used to initialize Time2 objects. 3...Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 4 public class Time2Test 5 { 6 public static void main(string args[]) 7 { 8 Time2 t1 = new Time2(); // 00:00:00 9 Time2 t2 = new Time2(2); // 02:00:00 10 Time2 t3 = new Time2(21,34); // 21:34:00 11 Time2 t4 = new Time2(12,25,42); // 12:25:42 12 Time2 t5 = new Time2(27,74,99); // 00:00:00 13 Time2 t6 = new Time2(t4); // 12:25:42 14 15 System.out.println( "Constructed with:" ); 16 System.out.println( "t1: all arguments defaulted" ); 17 ); System.out.printf( " %s\n", t1.touniversalstring() 18 System.out.printf( " %s\n", t1.tostring() ); 19 Κλήση υπερφορτωμένων κατασκευαστών και δημιουργία 6 αντικειμένων Time2
20 System.out.println( 21 "t2: hour specified; minute and second defaulted"); 22 System.out.printf(" %s\n", t2.touniversalstring()); 23 System.out.printf(" %s\n", t2.tostring()); 24...Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές 25 System.out.println( 26 "t3: hour and minute specified; second defaulted"); 27 System.out.printf(" %s\n", t3.touniversalstring()); 28 System.out.printf(" %s\n", t3.tostring()); 29 30 System.out.println("t4: hour, minute and second specified"); 31 System.out.printf(" %s\n", t4.touniversalstring()); 32 System.out.printf(" %s\n", t4.tostring()); 33 34 System.out.println("t5: all invalid values specified"); 35 System.out.printf(" %s\n", t5.touniversalstring()); 36 System.out.printf(" %s\n", t5.tostring()); 37 38 System.out.println("t6: Time2 object t4 specified"); 39 System.out.printf(" %s\n", t6.touniversalstring()); 40 System.out.printf(" %s\n", t6.tostring()); 41 } // end main 42 } // end class Time2Test
t1: all arguments defaulted 00:00:00 12:00:00 AM...Ανάλυση υπόθεσης Κλάσης Time: υπερφορτωμένοι κατασκευαστές t2: hour specified; minute and second defaulted 02:00:00 2:00:00 AM t3: hour and minute specified; second defaulted 21:34:00 9:34:00 PM t4: hour, minute and second specified 12:25:42 12:25:42 PM t5: all invalid values specified 00:00:00 12:00:00 AM t6: Time2 object t4 specified 12:25:42 12:25:42 PM
Επαναχρησιμοποίηση λογισμικού Ταχεία ανάπτυξη εφαρμογών (Rapid application development RAD) Επιταχύνει την ανάπτυξη δυναμικού, υψηλής ποιότητας λογισμικού Java s API Παρέχει ένα πλαίσιο εργασίας στο οποίο Java developers μπορούν να δουλέψουν για να πετύχουν πραγματική επαναληπτική χρήση και ταχεία ανάπτυξη εφαρμογών
Πακέτα Κάθε κλάση ανήκει σε ένα πακέτο Κλάσεις στο ίδιο πακέτο συνήθως εξυπηρετούν παρόμοιο σκοπό Τα πακέτα είναι όπως τα directories (folders) Κλάσεις από άλλα πακέτα πρέπει να γίνουν imported
Πακέτα Ορισμός πακέτων package path.to.package.foo; class Foo {... } Χρήση πακέτων import path.to.package.foo.foo; import path.to.package.foo.*;
Παράδειγμα package parenttools; public class BabyFood {... } package parenttools; public class Baby {... }
Παράδειγμα package adult; import parenttools.babyfood; import parenttools.baby; } public class Parent { public static void main (String[] args)} Baby baby = new Baby(); baby.feed(new BabyFood()); }
Βιβλιοθήκες Η Java περιλαμβάνει πολλές έτοιμες κλάσεις που ομαδοποιούνται σε υποκαταλόγους κατά κατηγορίες που ονομάζονται πακέτα (packages) Αυτό το σύνολο πακέτων αναφέρεται και ως βιβλιοθήκη κλάσεων της Java ή Java API (Application Programming Interface) Το πλήρες όνομα μιας κλάσης αποτελείται από τα ονόματα των πακέτων στα οποία ανήκει διαχωρισμένα με τελείες Π.χ. Javax.swing.JApplet
Τα πακέτα του Java API Η συμπερίληψη της δήλωσης import java.util.scanner; επιτρέπει στον προγραμματιστή να χρησιμοποιεί τη Scanner αντί για τη java.util.scanner Τεκμηρίωση του Java API και σύνοψη των πακέτων στο JDK 6.0 http://docs.oracle.com/javase/8/docs/api/ Η online τεκμηρίωση για το Java API παρέχει εύχρηστη αναζήτηση και πολλές λεπτομέρειες για κάθε κλάση Καθώς μαθαίνετε μία κλάση, θα πρέπει να αποκτήσετε τη συνήθεια να εντοπίζετε την κλάση στην online τεκμηρίωση για πρόσθετες πληροφορίες
java.util.scanner
Συμβουλή Μην προσπαθείτε να ανακαλύψετε και πάλι τον τροχό!! Όταν είναι εφικτό, επαναχρησιμοποιείστε τις κλάσεις και μεθόδους του Java API Μείωση του χρόνου ανάπτυξης του προγράμματος και αποφυγή εισαγωγής προγραμματιστικών σφαλμάτων Όλες οι κλάσεις «βλέπουν» κλάσεις του ιδίου πακέτου (δεν χρειάζεται import) Όλες οι κλάσεις «βλέπουν» κλάσεις του πακέτου java.lang Παράδειγμα: java.lang.string; java.lang.system
Βιβλιοθήκες Εν γένει για να χρησιμοποιήσουμε στοιχεία μιας βιβλιοθήκης πρέπει να δηλώσουμε στην αρχή του προγράμματος το όνομα της κλάσης που τα περιέχει Αυτό γίνεται με την εντολή import και ακολουθεί το πλήρες όνομα της κλάσης Εναλλακτικά, μπορούμε να καλούμε μία μέθοδο μιας κλάσης μέσα στον κώδικα χρησιμοποιώντας το πλήρες όνομά της, οπότε δεν χρειάζονται εντολές import Αν θέλουμε να χρησιμοποιήσουμε πολλές βιβλιοθήκες, για να μην εισάγουμε κάθε κλάση ξεχωριστά, χρησιμοποιούμε τον ειδικό χαρακτήρα (wildcard) * Για παράδειγμα, η εντολή import javax.swing.* επιτρέπει τη χρήση όλων των κλάσεων που ανήκουν στο πακέτο Swing
Βιβλιοθήκες Οι βασικές βιβλιοθήκες είναι πάντοτε φορτωμένες και τα στοιχεία τους, π.χ. οι μέθοδοί τους είναι άμεσα διαθέσιμες Το πακέτο java.lang εισάγεται αυτόματα σε όλα τα προγράμματα Για αυτό π.χ μπορούνε να καλέσουμε τη μέθοδο System.out.println() χωρίς κάποια εντολή import Σε περίπτωση μη κανονικού τερματισμού, το σωστό είναι να χρησιμοποιείται ο μηχανισμός εξαιρέσεων (exceptions) Τυπικά επιστρέφεται -1, αλλά μπορούμε να χρησιμοποιήσουμε και άλλες τιμές που θα υποδηλώνουν τον τύπο του σφάλματος που προέκυψε
...Τα πακέτα του Java API Package java.applet java.awt java.awt.event java.io java.lang Description The Java Applet Package contains a class and several interfaces required to create Java applets programs that execute in Web browsers. (Applets are discussed in Chapter 20, Introduction to Java Applets; interfaces are discussed in Chapter 10, Object_-Oriented Programming: Polymorphism.) The Java Abstract Window Toolkit Package contains the classes and interfaces required to create and manipulate GUIs in Java 1.0 and 1.1. In current versions of Java, the Swing GUI components of the javax.swing packages are often used instead. (Some elements of the java.awt package are discussed in Chapter 11, GUI Components: Part 1, Chapter 12, Graphics and Java2D, and Chapter 22, GUI Components: Part 2.) The Java Abstract Window Toolkit Event Package contains classes and interfaces that enable event handling for GUI components in both the java.awt and javax.swing packages. (You will learn more about this package in Chapter 11, GUI Components: Part 1 and Chapter 22, GUI Components: Part 2.) The Java Input/Output Package contains classes and interfaces that enable programs to input and output data. (You will learn more about this package in Chapter 14, Files and Streams.) The Java Language Package contains classes and interfaces (discussed throughout this text) that are required by many Java programs. This package is imported by the compiler into all programs, so the programmer does not need to do so.
...Τα πακέτα του Java API Package Description java.net java.text java.util javax.swing The Java Networking Package contains classes and interfaces that enable programs to communicate via computer networks like the Internet. (You will learn more about this in Chapter 24, Networking.) The Java Text Package contains classes and interfaces that enable programs to manipulate numbers, dates, characters and strings. The package provides internationalization capabilities that enable a program to be customized to a specific locale (e.g., a program may display strings in different languages, based on the user s country). The Java Utilities Package contains utility classes and interfaces that enable such actions as date and time manipulations, random-number processing (class Random), the storing and processing of large amounts of data and the breaking of strings into smaller pieces called tokens (class StringTokenizer). (You will learn more about the features of this package in Chapter 19, Collections.) The Java Swing GUI Components Package contains classes and interfaces for Java s Swing GUI components that provide support for portable GUIs. (You will learn more about this package in Chapter 11, GUI Components: Part 1 and Chapter 22, GUI Components: Part 2.) javax.swing.event The Java Swing Event Package contains classes and interfaces that enable event handling (e.g., responding to button clicks) for GUI components in package javax.swing. (You will learn more about this package in Chapter 11, GUI Components: Part 1 and Chapter 22, GUI Components: Part 2.)
Βιβλιοθήκες Όταν φτιάχνουμε προγράμματα που αποτελούνται από πολλές κλάσεις, τις εντάσσουμε στο ίδιο πακέτο βάζοντας ως πρώτη εντολή του αρχείου την package όνομαπακέτου Μέσα στο αρχείο ακολουθούν οι δηλώσεις των πακέτων/κλάσεων που χρησιμοποιούνται από την κλάση με τις εντολές Import και έπειτα ξεκινά η ίδια η κλάση ή περισσότερες κλάσεις
Βιβλιοθήκες [ package όνομαπακέτου; ] [ import όνομαβιβλιοθήκης; ]* [ class ΌνομαΚλάσης { } ] + σώμακλάσης Οι τετράγωνες παρενθέσεις [] υποδηλώνουν προαιρετική παρουσία Ο αστερίσκος * υποδηλώνει ότι μπορεί να υπάρχουν καμία, μία ή περισσότερες import και Ο σταυρός + ότι πρέπει να υπάρχει τουλάχιστον μία κλάση
Παρατηρήσεις Προκειμένου να επιτευχθεί η επαναχρησιμοποίηση κάθε μέθοδος θα πρέπει να περιορίζεται στην εκτέλεση μιας μοναδικής και σαφώς ορισμένης λειτουργίας Το όνομα της μεθόδου θα πρέπει να είναι αντιπροσωπευτικό της λειτουργίας της Τέτοιες μέθοδοι καθιστούν τα προγράμματα εύκολα στη συγγραφή, απασφαλμάτωση, συντήρηση αλλά και τροποποίησή τους Μία μικρή μέθοδος που εκπληρώνει μια ενέργεια είναι ευκολότερο να ελεγχθεί και απασφαλματωθεί από ότι μια μεγαλύτερη μέθοδος που κάνει πολλά πράγματα Αν δεν μπορείτε να επιλέξετε ένα λιτό και περιεκτικό όνομα που να περιγράφει τις ενέργειες μιας μεθόδου, η μέθοδός σας ενδέχεται να κάνει πολλά και διαφορετικά (ασυσχέτιστα) πράγματα Συνίσταται ο τεμαχισμός της μεθόδου αυτής σε περισσότερες δηλώσεις μικρότερων μεθόδων
Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) Κλάσεις από προϋπάρχουσες βιβλιοθήκες (π.χ. Java API) μπορούν να εισαχθούν σε πρόγραμμα Java Κάθε κλάση στο Java API ανήκει σε ένα πακέτο που περιέχει μία ομάδα σχετικών κλάσεων Τα πακέτα βοηθούν τους προγραμματιστές να χειρίζονται την πολυπλοκότητα των συσταικών εφαρμογών Βοηθούν επίσης την επαναληπτική χρήση λογισμικού επιτρέποντας στα προγράμματα να εισάγουν κλάσεις από άλλα πακέτα
Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) Για να δηλώσουμε μια επαναχρησιμοποιήσιμη κλάση Δηλώνουμε μια public class (αν δεν είναι public, τότε χρησιμοποιείται μόνο από κλάσεις του πακέτου) Προσθέτουμε μια δήλωση package στο αρχείο πηγαίου κώδικα Πρέπει να είναι η πρώτη εκτελέσιμη εντολή στο αρχείο Σύμβαση: Το όνομα του package θα πρέπει να αποτελείται από Internet domain name σε αντίστροφη σειρά ακολουθούμενο από άλλα ονόματα για το πακέτο Παράδειγμα: com.deitel.jhtp6.ch08 Μόνο δηλώσεις package, import και σχόλια μπoρούν να εμφανίζονται εκτός αγκίστρων δήλωσης κλάσης! Internet domain = deitel.com
1 // Fig. 8.18: Time1.java 2 // Time1 class declaration maintains the time in 24-hour format. 3 package com.deitel.jhtp6.ch08; Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων δήλωση package (Packages) 4 5 public class Time1 6 { 7 private int hour; // 0-23 8 private int minute; // 0-59 9 private int second; // 0-59 10 Η κλάση Time1 είναι μια public κλάση, άρα μπορεί να χρησιμοποιηθεί από «εισαγωγείς» αυτού του πακέτου 11 // set a new time value using universal time; perform 12 // validity checks on the data; set invalid values to zero 13 public void settime( int h, int m, int s ) 14 { 15 hour = ((h>=0 && h<24)? h : 0 ); // validate hour 16 minute = ((m>=0 && m<60)? m : 0 ); // validate minute 17 second = ((s>=0 && s<60)? s : 0 ); // validate second 18 } // end method settime 19
20 // convert to String in universal-time format (HH:MM:SS) 21 public String touniversalstring() 22 { 23 return String.format("%02d:%02d:%02d,hour,minute,second); Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) 24 } // end method touniversalstring 25 26 // convert to String in standard-time format (H:MM:SS AM or PM) 27 public String tostring() 28 { 29 return String.format( "%d:%02d:%02d %s", 30 ( ( hour == 0 hour == 12 )? 12 : hour % 12 ), 31 minute, second, ( hour < 12? "AM" : "PM" ) ); 32 } // end method tostring 33 } // end class Time1
Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) Μεταγλωττίζουμε την κλάση ούτως ώστε να τοποθετηθεί στην κατάλληλη δομή καταλόγου πακέτου Παράδειγμα: το πακέτο μας θα πρέπει να μπει στον κατάλογο αρχείων com deitel jhtp6 ch08 javac με όρισμα (command-line option) d Η εντολή javac δημιουργεί κατάλληλους καταλόγους αρχείων βασισμένη στη δήλωση του πακέτου στην κλάση Μια περίοδος (.) μετά από το d αναφέρεται στον τρέχοντα κατάλογο αρχείων javac d. Time1.java για να καθορίσουμε ότι ο πρώτος κατάλογος στο όνομα πακέτου μας πρέπει να τοποθετηθεί στον τρέχοντα κατάλογο
Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) Εισάγουμε την επαναχρησιμοποιήσιμη κλάση σε ένα πρόγραμμα Απλού-τύπου δήλωση εισαγωγής Εισάγει μια απλή κλάση Παράδειγμα: import java.util.random; Κατ αίτηση δήλωση εισαγωγής Εισάγει όλες τις κλάσεις σε ένα πακέτο Παράδειγμα: import java.util.*;
1 // Fig. 8.19: Time1PackageTest.java 2 // Time1 object used in an application. 3 import com.deitel.jhtp6.ch08.time1; // import class Time1 4 5 public class Time1PackageTest 6 { 7 public static void main( String args[] ) 8 { 9 // create and initialize a Time1 object Απλού-τύπου δήλωση εισαγωγής Αναφερόμαστε στην κλάση Time1 απλά με το όνομά της 10 Time1 time = new Time1(); // calls Time1 constructor 11 12 // output string representations of the time 13 System.out.print( "The initial universal time is: " ); 14 System.out.println( time.touniversalstring() ); 15 System.out.print( "The initial standard time is: " ); 16 System.out.println( time.tostring() ); 17 System.out.println(); // output a blank line 18
19 // change time and output updated time 20 time.settime( 13, 27, 6 ); 21 System.out.print("Universal time after settime is: "); 22 System.out.println( time.touniversalstring() ); Ανάλυση υπόθεσης Κλάσης Time: Δημιουργία Πακέτων (Packages) 24 System.out.println( time.tostring() ); 23 System.out.print("Standard time after settime is: ); 25 System.out.println(); // output a blank line 26 27 // set time with invalid values; output updated time 28 time.settime( 99, 99, 99 ); 29 System.out.println("After attempting invalid settings:"); 30 System.out.print( "Universal time: " ); 31 System.out.println( time.touniversalstring() ); 32 System.out.print( "Standard time: " ); 33 System.out.println( time.tostring() ); 34 } // end main 35 } // end class Time1PackageTest The initial universal time is: 00:00:00 The initial standard time is: 12:00:00 AM Universal time after settime is: 13:27:06 Standard time after settime is: 1:27:06 PM After attempting invalid settings: Universal time: 00:00:00 Standard time: 12:00:00 AM
Πρόσβαση Πακέτου Πρόσβαση πακέτου Μέθοδοι και μεταβλητές που δηλώνονται χωρίς τροποποιητικό πρόσβασης (public, protected, private) θεωρούνται ότι έχουν πρόσβαση πακέτων Κάτι τέτοιο δεν έχει νόημα σε προγράμματα που αποτελούνται από μία κλάση Αντιθέτως, αφορά προγράμματα που περιέχουν πολλές κλάσεις από το ίδιο πακέτο Τα μέλη με πρόσβαση πακέτου μπορούν να προσπελαστούν απευθείας μέσω των κατάλληλων αναφορών σε αντικείμενα άλλων κλάσεων που ανήκουν στο ίδιο πακέτο
1 // Fig. 8.20: PackageDataTest.java 2 // Package-access members of a class are accessible by other classes 3 // in the same package. 4...Πρόσβαση Πακέτου 5 public class PackageDataTest 6 { 7 public static void main( String args[] ) 8 { 9 PackageData packagedata = new PackageData(); 10 11 // output String representation of packagedata 12 System.out.printf( "After instantiation:\n%s\n",packagedata); 13 14 // change package access data in packagedata object 15 packagedata.number = 77; 16 packagedata.string = "Goodbye"; 17 18 // output String representation of packagedata Απευθείας προσπέλαση στα μέλη με πρόσβαση πακέτου 19 System.out.printf("\nAfter changing values:\n%s\n,packagedata); 20 } // end main 21 } // end class PackageDataTest 22
23 // class with package access instance variables 24 class PackageData 25 { 26 int number; // package-access instance variable 27 String string; // package-access instance variable...πρόσβαση Πακέτου 28 29 // constructor 30 public PackageData() 31 { 32 number = 0; 33 string = "Hello"; 34 } // end PackageData constructor 35 36 // return PackageData object String representation 37 public String tostring() 38 { 39 return String.format("number: %d; string: %s", number,string); 40 } // end method tostring 41 } // end class PackageData After instantiation: number: 0; string: Hello After changing values: number: 77; string: Goodbye Μεταβλητές στιγμιοτύπου με πρόσβαση πακέτου
Πηγές/Acknowledgements http://java.sun.com/j2se H. M. Deitel, P. J. Deitel, Java Προγραμματισμός, 6η έκδοση, Μ. Γκιούρδας, 2006 D. Barnes, M. Kolling, Αντικειμενοστρεφής Προγραμματισμός σε Java, Κλειδάριθμος, 2008 Βασίλης Χριστοφίδης, Αντικειμενοστρεφής Προγραμματισμός, Πανεπιστήμιο Κρήτης Κ. Τσαγκάρης, Εισαγωγή στις εφαρμογές της Java, Πανεπιστήμιο Πειραιώς Jones, Evan, Adam Marcus, and Eugene Wu. 6.092 Introduction to Programming in Java,January IAP 2010. (Massachusetts Institute of Technology: MIT OpenCourseWare), http://ocw.mit.edu (Accessed 10 Mar, 2013). License: Creative Commons BY-NC-SA