Προγραµµατισµός µε Java
Παναγιώτης Σφέτσος,
0
Εισαγωγή
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
1
Εισαγωγή
Πρόλογος Οι σηµειώσεις αυτές βασίζονται στην εµπειρία που έχουµε αντλήσει επί σειρά ετών από την διδασκαλία µας σε τµήµατα ΑΕΙ – ΤΕΙ και ΕΑΠ. Θεσσαλονίκη Φεβρουάριος 2003
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
2
Εισαγωγή
Εισαγωγή Η γλώσσα προγραµµατισµού Java είναι µία γλώσσα προγραµµατισµού που αναπτύσσεται πολύ γρήγορα. Κυκλοφόρησε σε πρώτη έκδοση το 1991 και έχει ήδη φθάσει στην 4η έκδοση της. Αποτελεί µία πλατφόρµα προγραµµατισµού ανεξάρτητη από τα διαφορετικά λειτουργικά συστήµατα και για τον λόγο αυτό χρησιµοποιείται περισσότερο σε Internet εφαρµογές. Είναι απλή, αντικειµενοστραφής, παρέχει ασφάλεια στις εφαρµογές και επειδή είναι ανεξάρτητη από τα διαφορετικά
λειτουργικά συστήµατα, χρησιµοποιείται για
εφαρµογές που δεν θα µπορούσαν να γίνουν µε τις λοιπές παραδοσιακές γλώσσες προγραµµατισµού. Αντικειµενοστραφής προγραµµατισµός (Object Oriented Programming – OOP), είναι ο προγραµµατισµός που χρησιµοποιεί σύνολα προγραµµατιστικών ενοτήτων που ονοµάζονται συστατικά ή αντικείµενα (objects). Τα αντικείµενα υφίστανται και δρουν ανεξάρτητα. Τα αντικείµενα επικοινωνούν µεταξύ τους αλλά και µε το περιβάλλον για να εκτελούν διάφορες εργασίες. Η δύναµη της Java δηλαδή, η ασφάλεια των εφαρµογών αλλά και η ανεξαρτησία της από τα διαφορετικά λειτουργικά συστήµατα, είναι ο Bytecode. Ο Bytecode είναι ο ενδιάµεσος κώδικας που παράγεται κατά την µεταγλώττιση του προγράµµατος και εκτελείται από τον διερµηνέα της ( Java Virtual Machine - JVM ). Με την δοµή αυτή επιτυγχάνεται η ασφαλής διακίνηση των εφαρµογών µέσα στο Internet αλλά και η εκτέλεση τους σε διαφορετικά λειτουργικά συστήµατα αρκεί να υπάρχει ο διερµηνέας της Java στα συστήµατα αυτά. Στο εγχειρίδιο αυτό θα µάθουµε να χρησιµοποιούµε την Java στην επίλυση προβληµάτων προγραµµατισµού, ξεκινώντας από τα πλέον απλά δηλαδή, της εκτέλεσης αριθµητικών πράξεων και εµβαθύνοντας σε δυσκολότερες έννοιες, όπως των αντικειµένων και των applets (προγράµµατα που µεταφέρονται µέσα από το Internet και εκτελούνται σε αυτό). Τα προγράµµατα στην Java είναι αρχεία κειµένου, που γράφονται σε απλούς επεξεργαστές. Τα προγράµµατα πρώτα µεταγλωττίζονται µε την κλήση του µεταγλωττιστή - javac και στην συνέχεια εκτελούνται στον διερµηνέα – java στη γραµµή εντολών. Η σύνταξη των προγραµµάτων πρέπει να γίνεται µε ιδιαίτερη προσοχή.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
3
Το πρώτο µας πρόγραµµα
Οι εργασίες εγκατάστασης •
Το Java Development Kit (JDK) είναι µια συλλογή προγραµµάτων που µπορούµε να ‘κατεβάσουµε’ χωρίς κόστος από την ιστοσελίδα της εταιρίας Sun (java.sun.com). Το πακέτο έρχεται µε όνοµα jdk1_x_x-XXX-win.exe, όπου τα x αντιπροσωπεύουν αριθµούς της τρέχουσας έκδοσης. Μετά πρέπει να κατεβάσουµε το εγχειρίδιο χρήσης που έρχεται σε συµπιεσµένη µορφή και µε το αντίστοιχο όνοµα jdk1_x_x-XXX-doc.zip. Το αρχείο αυτό πρέπει να το αποσυµπιέσουµε (unzip), ώστε να µπορέσουµε να διαβάσουµε τις οδηγίες και αντίστοιχες πληροφορίες της java.
Το πρώτο µας Πρόγραµµα •
Το παρακάτω απλό πρόγραµµα θα εµφανίσει στην οθόνη το µήνυµα : Hello Java.
/* Αυτό είναι ένα απλό πρόγραµµα στη Java Το όνοµα του αρχείου είναι Hello.java */ class Hello { // Το πρόγραµµα αρχίζει µε µία κλήση στη main() public static void main(String args[]) { System.out.println("Hello Java"); } }
•
Για να γράψουµε τον ανωτέρω κώδικα σε ένα απλό κειµενογράφο πρέπει να κάνουµε τα παρακάτω βήµατα: ¾ Πρώτα πηγαίνουµε σε παράθυρο του DOS (MS - DOS Prompt). Μετά πηγαίνουµε σε ένα κατάλογο όπου θα αποθηκεύουµε και θα εκτελούµε
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
4
Το πρώτο µας πρόγραµµα
τα προγράµµατά µας. Αν δεν υπάρχει τέτοιος κατάλογος τον δηµιουργούµε.
¾ Μετά καλούµε ένα απλό κειµενογράφο, για παράδειγµα τον Notepad, όπου θα γράψουµε το πρόγραµµα. (Programs | Accessories | Notepad).
¾ Γράφουµε το πρόγραµµα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
5
Το πρώτο µας πρόγραµµα
¾ Μπορούµε να χρησιµοποιήσουµε και άλλους κειµενογράφους όπως τους Edit, WordPad ή ακόµη και τον Ms – Word, αν αποθηκεύσουµε σωστά το πρόγραµµα δηλαδή, σε text – µορφή και µε κατάληξη java. To πρόγραµµα αυτό λέγεται πηγαίο πρόγραµµα (source program). ¾ Αποθηκεύουµε το πηγαίο πρόγραµµα µε το όνοµα Hello.java. ¾ Το πηγαίο πρόγραµµα πρέπει πρώτα να µεταγλωττισθεί, ώστε να
ελεγχθεί συντακτικά, και η εργασία αυτή γίνεται µε τον µεταγλωττιστή της java (compiler) - τον javac. Για να εκτελεσθεί ο javac πρέπει προηγουµένως να έχει ορισθεί η πλήρης διαδροµή (full path name) δηλαδή, η διαδροµή που θα επιτρέπει στο λειτουργικό σύστηµα να τον καλεί. Για παράδειγµα ορίζουµε την διαδροµή (path):
C:\Jdk1.2.2 \bin
Μεταγλώττιση και εκτέλεση του προγράµµατος ¾ Αν το όνοµα του πηγαίου προγράµµατος είναι Hello.java, τότε η εντολή για την µεταγλώττιση του προγράµµατος θα είναι :
C:\>javac Hello.java ¾ Η κατάληξη του προγράµµατος είναι η λέξη java, δηλαδή η κατάληξη περιέχει 4 - χαρακτήρες που δεν υποστηρίζει το λειτουργικό σύστηµα Dos. Για τον λόγο αυτό η java δεν τρέχει στο Dos, ενώ τρέχει σε περιβάλλον Windows 95 / 98 / και ΝΤ. Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
6
Το πρώτο µας πρόγραµµα
¾ Ο µεταγλωττιστής παράγει το αρχείο: Hello.class. Το αρχείο αυτό δεν είναι απ’ ευθείας εκτελέσιµο (executable), αλλά ένας ενδιάµεσος κώδικας – ο bytecode – που εκτελείται από τον διερµηνέα της java (Interpreter).
¾ Για να εκτελέσουµε το πρόγραµµα καλούµε τον διερµηνέα της java – (Interpreter) τον java µε την παρακάτω εντολή :
C:\>java MyProg ¾ Ο διερµηνέας της java λέγεται Java Virtual Machine (JVM) και εκτελεί τον bytecode – κώδικα. Ο κώδικας αυτός µπορεί να µεταφερθεί σε οποιοδήποτε λειτουργικό σύστηµα αρκεί να περιλαµβάνει τον αντίστοιχο JVM. Η δυνατότητα εκτέλεσης των bytecode – προγραµµάτων της java σε διαφορετικά λειτουργικά συστήµατα την έχει κάνει διάσηµη.
Τα
προγράµµατα διακινούνται και εκτελούνται µέσα στο Internet. Η εκτέλεση των προγραµµάτων γίνεται από τους πλοηγούς του Internet (Web – Browsers). Τα προγράµµατα αυτά ονοµάζονται applets.
H γενική δοµή του προγράµµατος /* <σχόλια> */ import
; // <σχόλια>
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
7
public class <όνοµα – κλάσης> <∆ηλώσεις Μεταβλητών> <∆ηλώσεις Μεθόδων>
Το πρώτο µας πρόγραµµα {
public static void main(String[] args) <εντολές προγράµµατος> }
{
}
•
Κάθε πρόγραµµα είναι µια µονάδα µεταγλώττισης.
•
Το πρόγραµµα της Java είναι ένα αρχείο – κειµένου που περιέχει µία ή περισσότερες Κλάσεις.
•
Κάθε Κλάση περιέχει τις δικές της εντολές προγράµµατος.
•
Στη χρήση των ονοµάτων πρέπει να λαµβάνεται υπόψη η διαφορά των κεφαλαίων και µικρών γραµµάτων.
Μία δεύτερη µατιά στο πρόγραµµα •
Σχόλια προγράµµατος πολλαπλών γραµµών. Αρχίζουν µε τα σύµβολα
/* και
τελειώνουν µε τα σύµβολα */. Τα σχόλια παραβλέπονται από τον µεταγλωττιστή. /* Αυτό είναι ένα απλό πρόγραµµα στη Java Το όνοµα του αρχείου είναι Hello.java */
•
Ορισµός της κλάσης του προγάµµατος µε το όνοµα της. Η κλάση αρχίζει µε το άγκιστρο { και κλείνει επίσης µε το άγκιστρο }. class Hello {
•
Σχόλιο προγράµµατος απλής γραµµής. Αρχίζει µε τα σύµβολα // και τελειώνει στο τέλος της γραµµής. // Το πρόγραµµα αρχίζει µε µία κλήση στη main()
•
Εντολή εκκίνησης της εκτέλεσης του προγράµµατος. Κάθε πρόγραµµα στη java καλεί την µέθοδο main().
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
8
Το πρώτο µας πρόγραµµα
public static void main(String args[])
•
public, καθορίζει ότι το πρόγραµµα θα έχει πρόσβαση στην κλάση – µέλος (καθολική ορατότητα). Το αντίθετο συµβαίνει µε την private, η οποία απαγορεύει την πρόσβαση στον κώδικα της κλάσης – µέλους (τοπική ορατότητα).
•
static,
επιτρέπει στην main() να κληθεί προς εκτέλεση πριν δηµιουργηθεί
κάποιο αντικείµενο στην κλάση – µέλος. •
void,
•
String args[ ] ή String[ ] args,
δηλώνει στον µεταγλωττιστή ότι η main() δεν επιστρέφει κάποια τιµή. ορίζει ένα πίνακα (array) παραµέτρων µε
όνοµα args µε τιµές της κλάσης String. Η args θα πάρει τιµές κατά την εκτέλεση του προγράµµατος (όχι βέβαια στο παράδειγµά µας). •
main(),
είναι η µέθοδος που καλείται όταν µία εφαρµογή java ξεκινά. Το
σώµα της περιέχεται µέσα σε άγκιστρα { }.
Η main() είναι το σηµείο
εκκίνησης του διερµηνέα. Μία εφαρµογή µπορεί να έχει δεκάδες κλάσεις αλλά µία από αυτές πρέπει να περιέχει την main(). •
Η τελευταία εντολή εµφανίζει στην οθόνη το µήνυµα χρησιµοποιώντας την µέθοδο println() και τις System.out που ορίζουν, η µεν πρώτη µία κλάση που παρέχει πρόσβαση στα µέσα του Συστήµατος, ενώ η δεύτερη την δέσµη εξόδου στην οθόνη. System.out.println("Hello Java");
•
Η εντολή τελειώνει µε το semicolon (;). Όλες οι εντολές της java τελειώνουν µε το σύµβολο αυτό.
•
Το πρώτο άγκιστρο κλείνει την main(), ενώ το δεύτερο την κλάση Hello.
•
Όταν το πρόγραµµα είναι µικρό περιέχει συνήθως µία κλάση. Στην περίπτωση αυτή θα πρέπει το όνοµα του πηγαίου κώδικα να είναι απόλυτα ίδιο µε το όνοµα της κλάσης.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
9
Προγραµµατισµός µε Java •
Το πρώτο µας πρόγραµµα
Προσέξτε για µία ακόµη φορά τον τρόπο σύνταξης των στοιχείων του προγράµµατος καθώς η java τα λαµβάνει σοβαρά υπ’ όψιν και επιστρέφει λάθος αν δεν ακολουθήσουµε τους κανόνες σύνταξης. Αν κάνουµε κάποιο συντακτικό
λάθος
θα
το
διορθώσουµε
χρησιµοποιώντας
ξανά
τον
κειµενογράφο.
Ο κύκλος Γράψε, Μεταγλώττισε, Εκτέλεσε.. 1. Γράψε το πρόγραµµα στο Notepad. 2. Αποθήκευσε το πρόγραµµα µε την εντολή Save As. 3. Μεταγλώττισε το πρόγραµµα µε την εντολή javac. 4. Αν έχουµε συντακτικά λάθη πηγαίνουµε στο βήµα 1. 5. Εκτέλεσε το πρόγραµµα µε την εντολή java. 6. Αν έχουµε λάθη πηγαίνουµε στο βήµα 1, ενώ αν εκτελείται σωστά τότε τελειώνουµε.
Παραλλαγή του προγράµµατος Hello •
Στην παραλλαγή θα περάσουµε µε παράµετρο το δεύτερο συνθετικό όνοµα της εµφάνισης του µηνύµατος. Προσέξτε την σύνταξη της args. Η πρώτη παράµετρος κατέχει την θέση 0 στη λίστα των παραµέτρων.
/* Αυτό είναι ένα απλό πρόγραµµα στη Java Το όνοµα του αρχείου είναι Hello.java */ class Hello { // Το πρόγραµµα αρχίζει µε µία κλήση στη main() public static void main(String args[]) { System.out.println("Hello " + args[0]); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
10
Το πρώτο µας πρόγραµµα
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το αποτέλεσµα: C:\>javac Hello.java C:\>java Hello Java Hello Java
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
11
Προγραµµατισµός µε Java
∆εδοµένα – Τελεστές - Μεταβλητές
Αρχικοί τύποι δεδοµένων Ακέραιοι και ∆εκαδικοί Αρχικοί τύποι Ακεραίων (Integer)
Τύπος Μέγεθος Όρια τιµών Byte
8 bits
-128 to +127
Short
16 bits
-32,768 to +32,767
Int
32 bits
(περίπου)-2 billion to +2 billion
Long
64 bits
(περίπου)-10E18 to +10E18
Αρχικοί τύποι ∆εκαδικών (Floating Point) Τύπος
Μέγεθος
Όρια τιµών
float
32 bits
-3.4E+38 to +3.4E+38
double
64 bits
-1.7E+308 to 1.7E+308
•
Γράφουµε ακέραιους : 123, 0, -34 (Integer literals, χωρίς υποδιαστολή).
•
Γράφουµε δεκαδικούς µε τα δεκαδικά ψηφία να χωρίζονται µε την τελεία : 123.0
•
-123.5
-198234.234
0.00000381
Γράφουµε επίσης δεκαδικούς µε επιστηµονική µορφή (scientific notation) χρησιµοποιώντας το E δηλαδή, 10 εις την δύναµη : 1.23E+02
-1.235E+02
-1.98234234E+05
3.81E-06
Για παράδειγµα ο αριθµός 1.2345E+03 είναι ο 1234.5 σε κανονική µορφή.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
12
∆εδοµένα – Τελεστές - Μεταβλητές
Ακρίβεια δεκαδικών αριθµών •
Ο τύπος δεδοµένων float έχει ακρίβεια 7 - δεκαδικών ψηφίων.
•
Ο τύπος δεδοµένων double έχει ακρίβεια περίπου 15 - δεκαδικών ψηφίων. Αν γράψουµε τον αριθµό 1.2345 θα θεωρηθεί του τύπου double και είναι ο τύπος που θα χρησιµοποιούµε για δεκαδικούς αριθµούς.
Ο αρχικός τύπος char •
Η java χρησιµοποιεί 16 – bits για την απεικόνιση ενός χαρακτήρα. Συνήθως χρησιµοποιούνται 8 – bits για απεικόνιση Αγγλικών χαρακτήρων και 16 – bits για χαρακτήρες άλλων γλωσσών. Η µέθοδος αυτή καλείται Unicode. Χαρακτήρες θεωρούνται επίσης τα σηµεία στίξης και το κενό διάστηµα. Τα κεφαλαία και τα πεζά γράµµατα θεωρούνται τελείως διαφορετικοί χαρακτήρες γι’ αυτό πρέπει να προσέχουµε ιδιαίτερα κατά τη σύνταξη των προγραµµάτων.
• Ένας χαρακτήρας γράφεται µέσα σε αποστρόφους ‘’. Για παράδειγµα ‘Α’, ‘ο’. Υπάρχουν και οι ‘controle’ - χαρακτήρες ή χαρακτήρες εντολών που συντάσσονται µε ιδικό τρόπο : '\n'
'\t'
'\377'
Ο αρχικός τύπος boolean •
Αντιπροσωπεύει µια απλή τιµή αλήθειας ή ψεύδους (true | false).
H κλάση string •
Κάθε αλυσίδα χαρακτήρων (string) είναι ένα αντικείµενο, ακόµη και οι σταθερές τύπου string. Είδαµε τις σταθερές τύπου string στην εντολή:
System.out.println(“Hello Java”);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
13
∆εδοµένα – Τελεστές - Μεταβλητές
Επειδή τα strings είναι αντικείµενα δεν µπορούν να µεταβληθούν απ’ ευθείας. Θα πρέπει να δηµιουργήσουµε ένα νέο string που θα περιέχει τις µεταβολές ή θα χρησιµοποιήσουµε την κλάση StringBuffer που επιτρέπει τις αλλαγές.
•
Η java ορίζει ένα τελεστή για τη συνένωση (concatenation) των strings, τον τελεστή
+.
Αριθµητικοί τελεστές Τελεστής
Εκτέλεση Πράξης
-
Πρόσηµο µείον - minus
+
Πρόσηµο συν – plus
*
Πολλαπλασιασµός
/
∆ιαίρεση
%
Υπόλοιπο
+
Πρόσθεση
-
Αφαίρεση
∆ήλωση Σταθερών (Constants) •
Χρησιµοποιώντας την δεσµευµένη λέξη
final
µπορούµε να δηλώσουµε
σταθερές τιµές µέσα στο πρόγραµµα δηλαδή, τιµές που δεν θα αλλάξουν κατά την εκτέλεση του προγράµµατος. class YpologismosFPA { public static void main ( String[] arg ) { final double SYNTELESTIS1 = 0.06; final double SYNTELESTIS2 = 0.18; . . . . . . } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
14
∆εδοµένα – Τελεστές - Μεταβλητές
Μεταβλητές (variables) •
Μεταβλητή, είναι ένας χώρος της µνήµης που θα πάρει τιµή µέσα στο πρόγραµµα ή κατά την εκτέλεση του προγράµµατος. Η µεταβλητή µπορεί να αλλάξει τιµή µέσα στο πρόγραµµα.
•
Πριν χρησιµοποιήσουµε µία µεταβλητή θα πρέπει να ορίσουµε το όνοµα και τον τύπο των δεδοµένων που θα λάβει.
Ονόµατα Μεταβλητών •
Το όνοµα της µεταβλητής αρχίζει µε ένα γράµµα, την underscore (_) ή το $ και µπορεί να περιέχει συνδυασµούς γραµµάτων και αριθµών.
•
Ένα πρόγραµµα αναφέρεται στην τιµή µιας µεταβλητής, χρησιµοποιώντας το όνοµα της. Το όνοµα της µεταβλητής πρέπει να αποτελείται από σειρές καταλλήλων Unicode χαρακτήρων, δηλαδή το σύστηµα κωδικοποίησης χαρακτήρων που υποστηρίζει κείµενο σε διαφορετικές γλώσσες όπως Ελληνική, Ιαπωνική, Εβραϊκή κ.ά.
•
Το όνοµα της µεταβλητής : 9 ∆εν πρέπει να είναι δεσµευµένη λέξη. 9 Πρέπει να είναι µοναδικό µέσα στο µπλόκ προγράµµατος που ορίζεται – scope.
Ασκήσεις µε χρήση Μεταβλητών Στο παρακάτω παράδειγµα: • • • •
ορίζουµε δύο µεταβλητές τις ar1 και ar2 στη συνέχεια δίνουµε τιµές στις µεταβλητές εκτελούµε απλές πράξεις εµφανίζουµε τα αποτελέσµατα
class Example1 { public static void main(String args[]) { int ar1;
//Ορίζει τη µεταβλητή ar1 που θα πάρει ακέραια τιµή
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java int ar2;
15
∆εδοµένα – Τελεστές - Μεταβλητές
//Ορίζει τη µεταβλητή ar2 που θα πάρει ακέραια τιµή
ar1 = 45; // δίνουµε στη ar1 την τιµή 45 ar2 = 20; // δίνουµε στη ar2 την τιµή 20 System.out.println("Arithmos1 : " + ar1); System.out.println("Arithmos2 : " + ar2); ar1 = ar1 * 2; ar2 = ar2 * 3; System.out.print("Apotelesma1 : ar1 * 2 = "); System.out.println(ar1); System.out.print("Apotelesma2 : ar2 * 3 = "); System.out.println(ar2); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
Arithmos1 : 45 Arithmos2 : 20 Apotelesma1 : ar1 * 2 = 90 Apotelesma2 : ar2 * 3 = 60
Εκτέλεση Πράξεων Κατανόηση της χρήσης των τελεστών •
Στην παρακάτω άσκηση θα δούµε την χρήση των τελεστών : ++x , x++, +x
και x+. class IncDec { public static void main(String args[]) { int x = 8, y = 13; System.out.println("x = " + x);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
16
∆εδοµένα – Τελεστές - Μεταβλητές
System.out.println("y = " + y); System.out.println("++x = " + ++x); System.out.println("y++ = " + y++); System.out.println("x = " + x); System.out.println("y = " + y); } }
• x = y = ++x y++ x = y = •
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: 8 13 = 9 = 13 9 14 Εκτέλεση απλών αριθµητικών πράξεων. Ένα πρώτο απλό παράδειγµα µε ακέραιους αριθµούς:
class Arithmetic { public static void main(String args[]) { int x = 17, y = 5; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("x + y = " + (x + y)); System.out.println("x - y = " + (x - y)); System.out.println("x * y = " + (x * y)); System.out.println("x / y = " + (x / y)); System.out.println("x % y = " + (x % y)); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: x y x x x x x
= = + * / %
17 5 y = y = y = y = y =
22 12 85 3 2
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
•
17
∆εδοµένα – Τελεστές - Μεταβλητές
Εκτέλεση απλών αριθµητικών πράξεων. Ένα δεύτερο απλό παράδειγµα µε πραγµατικούς αριθµούς:
class FloatMath { public static void main(String args[]) { float x = 23.5F, y = 7.3F; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("x + y = " + (x + y)); System.out.println("x - y = " + (x - y)); System.out.println("x * y = " + (x * y)); System.out.println("x / y = " + (x / y)); System.out.println("x % y = " + (x % y)); } }
x y x x x x x
• = = + * / %
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: 23.5 7.3 y = 30.8 y = 16.2 y = 171.55 y = 3.219178 y = 1.5999994
Ανάλυση της εκτέλεσης αριθµητικών πράξεων Πρόσθεση και αφαίρεση ακεραίων - Int Στο παρακάτω παράδειγµα: •
Ορίζουµε τρεις ακέραιες µεταβλητές a, b, c. ∆ίνουµε τιµές στις a = 1 και b = 2
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
18
∆εδοµένα – Τελεστές - Μεταβλητές
Εκτελούµε πρόσθεση και αφαίρεση των αριθµών a και b και τοποθετούµε το αποτέλεσµα στη µεταβλητή c.
•
Τέλος εµφανίζουµε τα αποτελέσµατα.
class Example2 { public static void main(String args[]) { int a = 1; int b = 2; int c; System.out.println("a = " + a); System.out.println("b = " + b); c = a + b; System.out.println("a + b = " + c); c = a - b; System.out.println("a - b = " + c); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
a = 1 b = 2 a + b = 3 a - b = -1
Πρόσθεση και αφαίρεση πραγµατικών - Double Στο παρακάτω παράδειγµα: •
Ορίζουµε τρεις µεταβλητές, που θα πάρουν πραγµατικές τιµές, τις a, b, c. ∆ίνουµε τιµές στις a = 8.5 και b = 6.5
•
Εκτελούµε πρόσθεση και αφαίρεση των αριθµών a και b και τοποθετούµε το αποτέλεσµα στη µεταβλητή c.
•
Τέλος εµφανίζουµε τα αποτελέσµατα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
19
∆εδοµένα – Τελεστές - Μεταβλητές
class Example3 { public static void main(String args[]) { double a = 8.5; double b = 6.5; double c; System.out.println("a = " + a); System.out.println("b = " + b); c = a + b; System.out.println("a + b = " + c); c = a - b; System.out.println("a - b = " + c); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: a = 8.5 b = 6.5 a + b = 15.0 a - b =
2.0
Πολλαπλασιασµός και ∆ιαίρεση ακεραίων Στο παρακάτω παράδειγµα: •
Ορίζουµε τρεις ακέραιες µεταβλητές a, b, c. ∆ίνουµε τιµές στις :
a = 20 και
b=2 •
Εκτελούµε πολλαπλασιασµό και διαίρεση των αριθµών a και b και τοποθετούµε το αποτέλεσµα στη µεταβλητή c.
•
Τέλος εµφανίζουµε τα αποτελέσµατα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
20
∆εδοµένα – Τελεστές - Μεταβλητές
class Example4 { public static void main(String args[]) { int a = 20; int b = 2; int c; System.out.println("a = " + a); System.out.println("b = " + b); c = a/b; System.out.println("a / b = " + c); c = a * b; System.out.println("a * b = " + c); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: a = 20 b = 2 a / b = 10 a * b = 40
Ο Τελεστής - υπόλοιπο διαίρεσης (%) Στο παρακάτω παράδειγµα: •
Ορίζουµε τρεις ακέραιες µεταβλητές a, b, c. ∆ίνουµε τιµές στις :
a = 10 και
b=3 •
Εκτελούµε την διαίρεση των αριθµών a και b µε τον τελεστή % και τοποθετούµε το αποτέλεσµα στη µεταβλητή c.
•
Τέλος εµφανίζουµε τα αποτελέσµατα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
21
∆εδοµένα – Τελεστές - Μεταβλητές
class Example5 { public static void main(String args[]) { int a = 10; int b = 3; int c; System.out.println("a = " + a); System.out.println("b = " + b); c = a%b; System.out.println("a % b = " + c); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τo αποτέλεσµα: a = 10 b = 3 a
%
b = 1
Πράξεις µε µεικτούς τύπους class Example6
{
public static void main(String[] args) { //Μεταβλητές διάφορων τύπων int i = 37; int j = 42; double x = 27.475; double y = 7.22; //Πρόσθεση αριθµών System.out.println("Adding..."); System.out.println("
i + j = " + (i + j));
System.out.println("
x + y = " + (x + y));
//Αφαίρεση αριθµών System.out.println("Subtracting..."); System.out.println("
i - j = " + (i - j));
System.out.println("
x - y = " + (x - y));
//Πολλαπλασιασµός αριθµών System.out.println("Multiplying...");
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
22
∆εδοµένα – Τελεστές - Μεταβλητές
System.out.println("
i * j = " + (i * j));
System.out.println("
x * y = " + (x * y));
//∆ιαίρεση αριθµών System.out.println("Dividing..."); System.out.println("
i / j = " + (i / j));
System.out.println("
x / y = " + (x / y));
//Υπολογισµός υπολοίπου διαίρεσης System.out.println("Computing the remainder..."); System.out.println("
i % j = " + (i % j));
System.out.println("
x % y = " + (x % y));
//Μεικτοί τύποι System.out.println("Mixing types..."); System.out.println("
j + y = " + (j + y));
System.out.println("
i * x = " + (i * x));
} }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: Adding... i + j = 79 x + y = 34.695 Subtracting... i - j = -5 x - y = 20.255000000000003 Multiplying... i * j = 1554 x * y = 198.36950000000002 Dividing... i / j = 0 x / y = 3.805401662049862 Computing the remainder... i % j = 37 x % y = 5.815000000000002 Mixing types... j + y = 49.22 i * x = 1016.575
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
23
∆εδοµένα – Τελεστές - Μεταβλητές
Πράξεις µε boolean – τελεστές •
Στην παρακάτω άσκηση θα δούµε την χρήση των λογικών τελεστών και τα αποτελέσµατα διαφόρων συγκρίσεων :
class Relational { public static void main(String args[]) { int x = 7, y = 11, z = 11; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("x < y = " + (x < y)); System.out.println("x > z = " + (x > z)); System.out.println("y <= z = " + (y <= z)); System.out.println("x >= y = " + (x >= y)); System.out.println("y == z = " + (y == z)); System.out.println("x != z = " + (x != z)); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
x = 7 y = 11 x < y = true x > z = false y <= z = true x >= y = false y == z = true x != z = true
String – τελεστές (συνένωση - concatenation) •
Στην παρακάτω άσκηση θα δούµε την συνένωση διαφόρων string :
class Concatenation { public static void main (String args[]) {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
24
∆εδοµένα – Τελεστές - Μεταβλητές
String firstHalf = "What " + "did "; String secondHalf = "you " + "say?"; System.out.println(firstHalf + secondHalf); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το αποτέλεσµα: What did you say?
Bitwise - λογικοί τελεστές •
Στην παρακάτω θα δούµε τους Bitwise – λογικούς τελεστές : |, &,
^, ~
class BitLogic { public static void main(String args[]) { String binary[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110","0111","1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int a = 3; // 0 + 2 + 1 or 0011 in binary int b = 6; // 4 + 2 + 0 or 0110 in binary int c = a | b; int d = a & b; int e = a ^ b; int f = (~a & b) | (a & ~b); int g = ~a & 0x0f; System.out.println("
a = " + binary[a]);
System.out.println("
b = " + binary[b]);
System.out.println("
a|b = " + binary[c]);
System.out.println("
a&b = " + binary[d]);
System.out.println("
a^b = " + binary[e]);
System.out.println("~a&b|a&~b = " + binary[f]); System.out.println("
~a = " + binary[g]);
} }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java a b a|b a&b a^b ~a&b|a&~b ~a
= = = = = = =
25
∆εδοµένα – Τελεστές - Μεταβλητές
0011 0110 0111 0010 0101 0101 1100
Στο παρακάτω παράδειγµα θα δούµε την χρήση του τελεστή: <<
•
class ByteShift { public static void main(String args[]) { byte a = 64, b; int i; i = a << 2; b = (byte) (a << 2); System.out.println("Original value of a: " + a); System.out.println("i and b: " + i + " " + b); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: Original value of a: 64 i and b: 256 0 Με τον τελεστή << µπορώ εύκολα να διπλασιάσω ένα αριθµό:
•
class MultByTwo { public static void main(String args[]) { int i; int num = 0xFFFFFFE; for(i=0; i<4; i++) { num = num << 1; System.out.println(num); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
26
∆εδοµένα – Τελεστές - Μεταβλητές
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: 536870908 1073741816 2147483632 -32 Οι bitwise – τελεστές έχουν συντµήσεις όπως και οι δεκαδικοί τελεστές.
•
class OpBitEquals { public static void main(String args[]) { int a = 1; int b = 2; int c = 3; a |= 4; b >>= 1; c <<= 1; a ^= c; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα: a = 3 b = 1 c = 6
Μετατροπές τύπων δεδοµένων Type Conversion and Casting •
Πολλές φορές η τιµή ενός τύπου καταχωρείται σε µεταβλητή άλλου τύπου
•
Όταν οι τιµές των µεταβλητών είναι συµβατού τύπου, τότε η java κάνει την µετατροπή αυτόµατα (για παράδειγµα από int σε long).
•
Οι επιτρεπτές µετατροπές αρχικών τύπων της java.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
•
27
∆εδοµένα – Τελεστές - Μεταβλητές
Όταν οι τιµές των µεταβλητών δεν είναι συµβατού τύπου, τότε η java κάνει την µετατροπή µε ένα cast: <µεταβλητή> = <επιθυµητός τύπος> τιµή
•
Το παρακάτω παράδειγµα δείχνει τέτοιες µετατροπές :
class Conversion { public static void main(String args[]) { byte b; int i = 257; double d = 323.142; System.out.println("\nConversion of int to byte."); b = (byte) i; System.out.println("i and b " + i + " " + b); System.out.println("\nConversion of double to int."); i = (int) d; System.out.println("d and i " + d + " " + i); System.out.println("\nConversion of double to byte."); b = (byte) d; System.out.println("d and b " + d + " " + b); } } •
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
Conversion of int to byte. i and b 257 1 Conversion of double to int. d and i 323.142 323 Conversion of double to byte. d and b 323.142 67
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
28
Προγραµµατισµός µε Java
∆εδοµένα – Τελεστές - Μεταβλητές
Λοιπές ασκήσεις πράξεων και τύπων δεδοµένων Στην παρακάτω άσκηση θα δούµε τη χρήση της σταθεράς MAX_VALUE που επιστρέφει τη µέγιστη τιµή για ένα τύπο δεδοµένων. class MaxValues { public static void main(String args[]) { // Ακέραιοι byte largestByte
= Byte.MAX_VALUE;
short
largestShort
= Short.MAX_VALUE;
int
largestInteger = Integer.MAX_VALUE;
long
largestLong
// Πραγµατικοί float largestFloat
= Long.MAX_VALUE;
= Float.MAX_VALUE;
double largestDouble
= Double.MAX_VALUE;
// Άλλοι πρωταρχικοί τύποι char aChar = 'S'; boolean aBoolean = true; // Εµφάνιση όλων System.out.println("The largest byte
: " + largestByte);
System.out.println("The largest short
: " + largestShort);
System.out.println("The
largest
integer
:
"
+
largestInteger); System.out.println("The largest long
: " + largestLong);
System.out.println("The largest float
: " + largestFloat);
System.out.println("The largest double
: " + largestDouble);
if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); } else { System.out.println("The
character
"
value
of
+
aChar
+
"
is
lower
case.");
} System.out.println("The
aBoolean
is
"
+
aBoolean); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
29
Προγραµµατισµός µε Java •
∆εδοµένα – Τελεστές - Μεταβλητές
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
The largest byte
: 127
The largest short
: 32767
The largest integer : 2147483647 The largest long
: 9223372036854775807
The largest float
: 3.4028235E38
The largest double
: 1.7976931348623157E308
The character S is upper case. The value of aBoolean is true •
Για ακέραιους µε πολλά ψηφία χρησιµοποιούµε τον τύπο long. Στην παρακάτω άσκηση θα υπολογίσουµε την απόσταση που διανύει το φως σε 1000 µέρες, όταν γνωρίζουµε ότι η ταχύτητα του φωτός είναι 186000 µίλια το δευτερόλεπτο και η σχέση υπολογισµού είναι η παρακάτω: Απόσταση = Ταχύτητα * ∆ευτερόλεπτα
class Distance { public static void main(String args[]) { int lightspeed; long days; long seconds; long distance; // Η ταχύτητα του φωτός σε µίλια ανά δευτερόλεπτο lightspeed = 186000; days = 1000;
// Ο υπολογισµός για 1000 µέρες
seconds = days * 24 * 60 * 60; // µετατροπή σε δευτερόλεπτα distance = lightspeed * seconds;
//υπολογισµός της απόστασης
System.out.print("In " + days); System.out.print(" days light will travel about "); System.out.println(distance + " miles"); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
30
∆εδοµένα – Τελεστές - Μεταβλητές
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το αποτέλεσµα: In 1000 days light will travel about 16070400000000 miles
•
Στην παρακάτω άσκηση θα υπολογίσουµε την ενέργεια ενός Ηλεκτρονίου σύµφωνα µε την σχέση του Αϊνστάιν E = mc2
class mc2 { public static void main (String args[]) { double mass = 9.1096E-25; double c = 2.998E8; double E = mass * c * c; System.out.println(E); } }
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το αποτέλεσµα: 8.18771e-08
Η ανάθεση τιµής - assignment Το σύµβολο της ανάθεσης τιµής σε µεταβλητές ή σταθερές το είδαµε ήδη από τις προηγούµενες ασκήσεις. Το σύµβολο της ανάθεσης τιµής είναι το απλό ίσον (=), όπως και στις περισσότερες γλώσσες προγραµµατισµού. Η γενική
µορφή του
τελεστή είναι: var = < έκφραση>. Παράδειγµα int x, y, z; x = y = z = 35;
//εκχωρεί την τιµή 35 στις µεταβλητές x, y και z.
Ο τελεστής ? • Είναι ο τελεστής τριών – δρόµων και χρησιµοποιείται για να αντικαταστήσει κάποιες πολλαπλές συγκρίσεις µε τις if – then – else εντολές. Η γενική µορφή του τελεστή είναι: <έκφραση1> ? <έκφραση2> : <έκφραση3> Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
31
Προγραµµατισµός µε Java •
∆εδοµένα – Τελεστές - Μεταβλητές
Η <έκφραση1> είναι µια λογική έκφραση και µπορεί να πάρει τιµή true ή false. Αν η <έκφραση1> επιστρέψει τιµή αλήθειας (true), τότε εκτελείται η <έκφραση2>, διαφορετικά εκτελείται η <έκφραση3>.
•
Παράδειγµα: z = y == 0
?
0
:
x
/
y ;
Στο ανωτέρω παράδειγµα αν η y είναι 0, τότε εκτελείται η έκφραση µεταξύ του (?) και του (:) δηλαδή, το z =0. Αν η y δεν είναι µηδέν, τότε εκτελείται η έκφραση µετά το (:) δηλαδή θα εκτελεσθεί η διαίρεση x / y. •
Στην παρακάτω άσκηση θα δούµε επίσης τη χρήση του τελεστή ?.
class Ternary { public static void main(String args[]) { int i, k; i = 10; k = i < 0 ? -i : i; // απόλυτη τιµή του i System.out.print("Absolute value of "); System.out.println(i + " = " + k); i = -10; k = i < 0 ? -i : i; // απόλυτη τιµή του i System.out.print("Absolute value of "); System.out.println(i + " = " + k); } } •
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα αποτελέσµατα:
Absolute value of 10 = 10 Absolute value of -10 = 10
Προτεραιότητα εκτέλεσης πράξεων •
Η σειρά εκτέλεσης πράξεων σε µία έκφραση γίνεται από αριστερά προς τα δεξιά. Έτσι στη σχέση c = 2 * 6 + 16 / 4 θα παίρναµε πρώτα το 2 * 6 = 12, ύστερα το 12 + 16 = 28, µετά το 28 / 4 = 7 και θα το είχαµε σαν
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
32
Προγραµµατισµός µε Java
∆εδοµένα – Τελεστές - Μεταβλητές
τελικό αποτέλεσµα στη µεταβλητή c. Στην πραγµατικότητα το αποτέλεσµα είναι διαφορετικό (2 * 6 = 12, 16 / 4 = 4, 12 + 4 = 16 και τέλος c =16), αν δούµε τις προτεραιότητες στον παρακάτω πίνακα :
()
[]
.
++
--
~
*
/
%
+
-
>>
>>> <<
>
>=
==
!=
<
!
<=
& ^ | && || ?: =
op=
Ασκήσεις •
Ένας υπάλληλος πληρώθηκε για µηνιαίο µισθό:
20 δεκαχίλιαρα, 10
πεντοχίλιαρα, 20 χιλιάρικα, 25 πεντακοσάρικα, 32 εκατοστάρικα και 15 πενηντάρικα. Να υπολογίσετε πόσος είναι τελικά ο µηνιαίος µισθός του υπάλληλου.
•
Να γίνει το πρόγραµµα που εµφανίζει την καρτέλα µε τα στοιχεία ενός πελάτη µιας επιχείρησης. Τα δεδοµένα για τον πελάτη θα εισαχθούν µέσα στο πρόγραµµα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
33
∆εδοµένα – Τελεστές - Μεταβλητές
Να υπολογισθεί και εµφανισθεί η Τελική τιµή ενός προϊόντος όταν γνωρίζουµε ότι η Αρχική του τιµή είναι 1000 ∆ρχµ. και ο συντελεστής Φ.Π.Α είναι 18%. Να υπολογίσετε πρώτα το ποσό Φ.Π.Α (Αρχική τιµή * συντελεστή Φ.Π.Α / 100) και έπειτα την Τελική τιµή ( Αρχική τιµή + Ποσό Φ.Π.Α).
•
Να γίνει το πρόγραµµα που υπολογίζει τον ακαθάριστο µισθό ενός υπαλλήλου όταν γνωρίζουµε ότι οι µέρες εργασίας του υπαλλήλου είναι 25, το ηµεροµίσθιο 20000, οι υπερωρίες 10 ώρες και τέλος η σχέση υπολογισµού είναι: Ακαθ.Μισθός = Μέρες Εργ. * Ηµεροµίσθιο + 0.2 * Ηµεροµίσθιο * Υπερωρίες
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
34
Εντολές Ελέγχου
Λογικοί τελεστές – boolean Τελεστής
Έλεγχος που εκτελεί
A
==
A
<
A
<=
A
>
A
>=
B
Είναι το A µεγαλύτερο ή ίσο του B ;
A
!=
B
Είναι το A όχι ίσο (άνισο) του B ;
•
B
Είναι το A ίσο µε το B ; Είναι το A µικρότερο του B ;
B
B
Είναι το A µικρότερο ή ίσο του B ; Είναι το A µεγαλύτερο του B ;
B
Οι λογικοί τελεστές µε τα ορίσµατα Α και Β αποτελούν τις λογικές εκφράσεις. Θα δούµε τις λογικές εκφράσεις σε πρώτη φάση στις εντολές if και switch.
Εντολή - if •
Εντολή αλλαγής της ροής του προγράµµατος σύµφωνα µε τη λογική τιµή µιας έκφρασης. if
<συνθήκη>
<εντολή1 | δέσµη εντολών1> else < εντολή2
| δέσµη εντολών2>
Φωλιασµένες if (nested) •
Εντολές if που αποτελούν µέρος άλλης if ή else λέγονται φωλιασµένες ή εστιασµένες if.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
35
Εντολές Ελέγχου
H κλιµακωτή εντολή if – else if •
Για πολλαπλούς ελέγχους χρησιµοποιούµε τη κλιµακωτή if – else if εντολή. if
<συνθήκη> <εντολή> ;
else if <συνθήκη> <εντολή>
else if <συνθήκη> <εντολή>
: else <εντολή>
•
Παράδειγµα χρήσης της if – else if class IfElse { public static void main(String args[]) { int month = 4; // April String season; if(month == 12 || month == 1 || month == 2) season = "Winter"; else if(month == 3 || month == 4 || month == 5) season = "Spring"; else if(month == 6 || month == 7 || month == 8) season = "Summer"; else if(month == 9 || month == 10 || month == 11) season = "Autumn"; else season = "Error in Month"; System.out.println("April is in the " + season + "."); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
36
Εντολές Ελέγχου
Εντολή – switch •
Εντολή πολλαπλών αποφάσεων – διαδροµών. switch <έκφραση>
{
case <τιµή 1> ; // σειρά εντολών
break ; case <τιµή 2> ; // σειρά εντολών
break ; : : default ;
// σειρά εντολών
} •
Η έκφραση πρέπει να είναι του τύπου byte, short, int, ή char. Η default είναι προαιρετική.
•
Παράδειγµα χρήσης της if – else if
class SampleSwitch { public static void main(String args[]) { for(int i=0; i<6; i++) switch(i) { case 0: System.out.println("i is zero."); break; case 1: System.out.println("i is one."); break; case 2: System.out.println("i is two."); break;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
37
Προγραµµατισµός µε Java
Εντολές Ελέγχου
case 3: System.out.println("i is three."); break; default: System.out.println("i is greater than 3."); }
}
}
Φωλιασµένες switch •
Εντολή switch µέσα σε άλλη δηµιουργεί φωλιασµένες switch – εντολές. switch (counter1) { case
1: switch (counter2) case
{
0: System.out.println(“Value is zero”); break;
case
1: System.out.println(“Value is one”); break;
} break; case
2:
:
Εντολές επανάληψης •
Οι εντολές επανάληψης της java είναι οι : for, while και do – while. Αυτές οι εντολές δηµιουργούν θηλιές (loops). Οι εντολές που περικλείονται µέσα στις θηλιές εκτελούνται συνήθως µέχρις ότου εκτελεσθεί µία συνθήκη τερµατισµού.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
38
Εντολές Ελέγχου
Eντολή – for •
Είναι η εντολή που εκτελείται για προκαθορισµένο αριθµό επαναλήψεων. for (<αρχική τιµή> ; <συνθήκη τερµατισµού>; <βήµα επανάληψης>)
•
Επανάληψη της θηλιάς για 10 – φορές. for (i=1;
i<11;
i++)
System.out.println(i);
•
Επανάληψη της θηλιάς για 10 – φορές. Προσέξτε τις τιµές του i. class Forloop1 { public static void main(String args[]) { int i; for(i=10; i>0; i--) System.out.println("Number : " + i); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Number Number Number Number Number Number Number Number Number Number
: : : : : : : : : :
10 9 8 7 6 5 4 3 2 1
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
39
Εντολές Ελέγχου
Μπορούµε να ορίσουµε την µεταβλητή της θηλιάς µέσα στην ίδια την θηλιά, όταν δεν θέλουµε να την χρησιµοποιήσουµε έξω από τη θηλιά.
class ForLoop2 { public static void main(String args[]) { // εδώ η i ορίζεται µέσα στη θηλιά for(int i=10; i>0; i--) System.out.println("Number : " + i); } }
•
Στο παρακάτω παράδειγµα η συνθήκη τερµατισµού είναι boolean και όχι συνθήκη τιµής.
Boolean ok = false; for (int I = 1; ! ok; I++) {
// … if (metr >10) ok = true;
: •
Στο παρακάτω παράδειγµα θα χρησιµοποιήσουµε θηλιά όπου όµως η τιµή εκκίνησης και το βήµα της επανάληψης ορίζονται έξω από αυτήν.
class ForVar { public static void main(String args[]) { int i; boolean done = false; i = 0; for( ; !done; ) { System.out.println("i is " + i); if(i == 10) done = true; i++; }
}
}
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
40
Εντολές Ελέγχου
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: i is 0 i is 1 i is 2 i is 3 i is 4 i is 5 i is 6 i is 7 i is 8 i is 9 i is 10
•
Ατέρµονη θηλιά θα έχουµε όταν δεν ορίσουµε τα τρία µέρη της. Για παράδειγµα:
for ( ; ; ) { //.. }
Φωλιασµένες for •
Μία θηλιά - for που εκτελείται µέσα σε άλλη.
•
Ένα παράδειγµα φωλιασµένων - for θα δούµε στο παρακάτω παράδειγµα.
class ForNested { public static void main(String args[]) { int i, j; for(i=0; i<10; i++) { for(j=i; j<10; j++) System.out.print("*"); System.out.println(); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
41
Εντολές Ελέγχου
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα:
********** ********* ******** ******* ****** ***** **** *** ** *
Εντολή - while •
Επαναλαµβάνει µία ή περισσότερες εντολές όσο ισχύει µία συνθήκη που ελέγχεται σε κάθε επανάληψη. while <συνθήκη> { //
σώµα της θηλιάς
} •
Η τιµή της συνθήκης τερµατίζει τη θηλιά. Όταν η συνθήκη πάρει ψευδή τιµή λόγω του ότι είναι boolean, τότε η θηλιά θα τερµατιστεί και θα εκτελεστεί η αµέσως µετά την while – εντολή.
•
Στο παρακάτω παράδειγµα θα δούµε µία θηλιά να εκτελείται 10 – φορές µε φθίνουσα µέτρηση δηλαδή, από το 10 προς το 1. class DemoWhile { public static void main(String args[]) { int i = 10; while(i > 0) { System.out.println("Number : " + i); i--; } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
42
Εντολές Ελέγχου
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Number : 10
•
Number :
9
Number :
8
Number :
7
Number :
6
Number :
5
Number :
4
Number :
3
Number :
2
Number :
1
Η while µπορεί να µην έχει σώµα δηλαδή, να έχει µια τέτοια µορφή: while (++ i < --i);
Εντολή do - while •
Είναι η εντολή επανάληψης κατά την οποία το σώµα της θηλιάς εκτελείται τουλάχιστον µία φορά. Στη θηλιά αυτή ο έλεγχος της συνθήκης γίνεται στο τέλος της και όχι στην αρχή της όπως η while. do
{ // σώµα θηλιάς
} while <συνθήκη> •
Πρώτα εκτελείται το σώµα της θηλιάς και µετά ελέγχεται η συνθήκη. Αν η τιµή της συνθήκης είναι αληθής, τότε θα συνεχιστεί η εκτέλεση της θηλιάς, διαφορετικά θα τερµατιστεί και θα εκτελεστεί η αµέσως επόµενη εντολή.
•
Στο παρακάτω παράδειγµα θα δούµε όπως και στην while µία θηλιά να εκτελείται 10 – φορές µε φθίνουσα τάξη : 10, 9, 8,….,1.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
43
Εντολές Ελέγχου
class DoWhile { public static void main(String args[]) { int i = 10; do { System.out.println("Number : " + i); i--; } while(i > 0); } }
•
Στο ανωτέρω παράδειγµα η εντολή do – while θα µπορούσε να γραφεί και µε τον παρακάτω τρόπο :
do System.out.println("Number : " + i); while (--i > 0);
Ο διαχωριστής comma στη for – θηλιά •
Μία παραλλαγή της for είναι η µορφή όπου δίνουµε αρχικές τιµές στις µεταβλητές της θηλιάς. Έτσι αν είχαµε τον παρακάτω κώδικα θα µπορούσαµε να γράψουµε τις τιµές b = 4 και b -- µέσα στον ορισµό της for. class Sample { public static void main(String args[]) { int a, b; b = 4; for(a=1; a
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
44
Εντολές Ελέγχου
Ο κώδικας µε τη νέα µορφή θα µπορούσε να είναι: class Comma { public static void main(String args[]) { int a, b; for(a=1, b=4; a
}
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: a = 1 b = 4 a = 2 b = 3
Εντολές εξόδου •
Είναι οι εντολές που τερµατίζουν τις θηλιές. Οι εντολές αυτές είναι οι : break, continue και return.
Η χρήση της break •
Χρησιµοποιείται: 9 στην εντολή switch για τον τερµατισµό του κάθε case. 9 για τον τερµατισµό µιας θηλιάς. 9 αντί µίας ‘εξευγενισµένης’ – goto εντολής.
•
Όταν εκτελεσθεί η break µέσα σε θηλιά, τότε θα τερµατισθεί και θα εκτελεσθεί η αµέσως επόµενη εντολή.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
45
Εντολές Ελέγχου
Στο παρακάτω παράδειγµα θα δούµε τη χρήση της break µέσα σε θηλιά. H θηλιά αντί να εκτελεσθεί από το 0 έως το 99 εκτελείται µόνο 10 – φορές. class BreakLoop { public static void main(String args[]) { for(int i=0; i<100; i++) { if(i == 10) break; // τερµατίζει τη θηλιά ότα το i γίνει 10
System.out.println("i: " + i); } System.out.println("End of the Loop"); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: i: 0 i: 1 i: 2 i: 3 i: 4 i: 5 i: 6 i: 7 i: 8 i: 9 End of the loop
•
Τα ίδια αποτελέσµατα µε τα ανωτέρω θα πάρουµε αν εκτελέσουµε τον παρακάτω κώδικα µε την while : class BreakLoop2 { public static void main(String args[]) { int i = 0; while(i < 100) { if(i == 10) break; // τερµατίζει τη θηλιά ότα το i γίνει 10
System.out.println("i: " + i); }
}
i++;
System.out.println("End of the Loop");
}
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
46
Εντολές Ελέγχου
Όταν η break βρίσκεται στην εσωτερική θηλιά δύο φωλιασµένων θηλιών, προκαλεί τον τερµατισµό της εσωτερικής µόνο θηλιάς. class BreakLoop3 { public static void main(String args[]) { for(int i=0; i<3; i++) { System.out.print("Outer " + i + ": "); for(int j=0; j<100; j++) { if(j == 10) break; //τερµατίζει τη θηλιά ότα το i γίνει 10 System.out.print(j + " "); } System.out.println(); } System.out.println("End of the Loop "); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Outer 0: 0 1 2 3 4 5 6 7 8 9 Outer 1: 0 1 2 3 4 5 6 7 8 9 Outer 2: 0 1 2 3 4 5 6 7 8 9 End of the loop
•
Στα παρακάτω παραδείγµατα θα δούµε τη χρήση της break σαν goto – εντολή µιας και δεν υπάρχει αυτή η εντολή στη java. Αυτό δεν σηµαίνει ότι θα χρησιµοποιούµε την break σαν εντολή – goto. class Break { public static void main(String args[]) { boolean t = true; first: { second: { third: { System.out.println("Before the break"); if(t) break second; // τερµατίζει το 2ο block System.out.println("This won't execute"); } System.out.println("This won't execute");
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
47
Εντολές Ελέγχου
} System.out.println("Αfter the break"); } } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα:
Before the break After the break
•
Προσέξτε στο ανωτέρω παράδειγµα την σύνταξη της εντολής break <ετικέτα>. Στο παρακάτω παράδειγµα σε φωλιασµένες θηλιές, µε την χρήση της break σαν goto – εντολή θα τερµατίσουµε την εξωτερική θηλιά.
class BreakLoop4 { public static void main(String args[]) { outer: for(int i=0; i<3; i++) { System.out.print("Outer " + i + ": "); for(int j=0; j<100; j++) { if(j == 10) break outer; //τερµατισµός των 2-θηλιών System.out.print(j + " "); }
System.out.println("This will not print"); }
System.out.println("End of loops"); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Outer 0: 0 1 2 3 4 5 6 7 8 9 End of the loops
Εντολή – continue •
Όταν εκτελεσθεί η εντολή continue, παραλείπεται το υπόλοιπο κοµµάτι κώδικα και η ροή του προγράµµατος µεταφέρεται στην συνθήκη ελέγχου της θηλιάς.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
48
Εντολές Ελέγχου
class DemoContinue { public static void main(String args[]) { for(int i=0; i<10; i++) { System.out.print(i + " "); if (i%2 == 0) continue; System.out.println(""); }
}
}
•
Στο προηγούµενο πρόγραµµα
χρησιµοποιούµε τον τελεστή % για να
ελέγξουµε αν το i είναι ζυγό. Αν είναι ζυγό, τότε η θηλιά συνεχίζει χωρίς να εµφανίζει στην οθόνη νέα γραµµή. •
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: 0 2 4 6 8
•
1 3 5 7 9
Όπως και µε τη break µπορούµε να χρησιµοποιήσουµε
ετικέτα
για να
αλλάξουµε τη ροή του προγράµµατος. Στο παρακάτω παράδειγµα υπολογίζεται ο τριγωνικός πίνακας πολλαπλασιασµού των αριθµών από το 0 έως το 9. class ContinueLabel { public static void main(String args[]) { outer: for (int i=0; i<10; i++) { for(int j=0; j<10; j++) { if(j > i) { System.out.println(); continue outer; }
System.out.print(" " + (i * j)); } }
System.out.println(); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
49
Εντολές Ελέγχου
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα:
0 01 024 0369 0 4 8 12 16 0 5 10 15 20 25 0 6 12 18 24 30 36 0 7 14 21 28 35 42 49 0 8 16 24 32 40 48 56 64 0 9 18 27 36 45 54 63 72 81
Εντολή - return •
H εντολή αυτή τερµατίζει µία µέθοδο και επιστρέφει την ροή του προγράµµατος στο καλόν της µεθόδου πρόγραµµα. Στο παρακάτω πρόγραµµα η ροή θα επιστρέψει στην έξοδο επειδή η main() είναι η µέθοδος που καλείται από τον διερµηνευτή της java. class Return { public static void main(String args[]) { boolean t = true; System.out.println("Before the return"); If(t) return; // Επιστροφή στο καλόν πρόγραµµα System.out.println("Not shown"); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
50
Εντολές Ελέγχου
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτελέσµα: Before the return
•
Όπως βλέπουµε η εντολή println() δεν εκτελείται. Μετά την εκτέλεση της return η ροή του προγράµµατος επιστρέφει στο λειτουργικό σύστηµα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
51
Είσοδος – Έξοδος ( Ι / Ο )
Εργασίες Input – Output ( I / O) •
Οι εφαρµογές της Java είναι ως επί το πλείστον γραφικές παραθυρικές εφαρµογές και βασίζονται επάνω στο εργαλείο Java’s Abstract Window Toolkit (AWT). H είσοδος των δεδοµένων εποµένως στα προγράµµατα γίνεται µέσα από όµορφο και φιλικό προς τον χρήστη γραφικό περιβάλλον και όχι µέσα από το τερµατικό του υπολογιστή. Παρόλα αυτά θα µάθουµε να χρησιµοποιούµε τις µεθόδους εισόδου και εξόδου από το τερµατικό.
•
Οι εργασίες Ι / Ο γίνονται µέσα από δέσµες συνεχούς ροής (streams) που συνδέονται µε τις φυσικές µονάδες. Με τον τρόπο αυτό οι ίδιες κλάσεις και µέθοδοι εφαρµόζονται για οποιαδήποτε συσκευή. Έτσι για παράδειγµα µια τέτοια δέσµη εισόδου µπορεί να χειριστεί οποιαδήποτε είσοδο δηλαδή, είτε είσοδο από το τερµατικό είτε είσοδο από αρχείο.
•
Η βιβλιοθήκη χειρισµού των κλάσεων και µεθόδων Ι / Ο είναι το πακέτο
java.io. •
H Java ορίζει δύο τύπους δέσµης συνεχούς ροής : τον byte και character
stream. •
Οι δέσµες Byte streams χειρίζονται εισόδους και εξόδους των bytes. Τέτοιες εισόδους και εξόδους έχουµε για παράδειγµα όταν διαβάζουµε ή γράφουµε δυαδικά δεδοµένα.
•
Οι δέσµες Character streams χειρίζονται εισόδους και εξόδους χαρακτήρων. Χρησιµοποιούν την δέσµη χαρακτήρων Unicode και για τον λόγο αυτό εφαρµόζονται σε διεθνείς εφαρµογές. Οι δέσµες αυτές είναι και πιο αποτελεσµατικές από ότι οι δέσµες byte.
•
Οι δέσµες Character προστέθηκαν στη Java µε την έκδοση 1.1. Πάντως οι χαµηλού επιπέδου επεξεργασίες Ι / Ο εξακολουθούν να γίνονται µε δέσµες byte.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
52
Είσοδος – Έξοδος ( Ι / Ο )
Οι κλάσεις - Byte stream • Η Java ορίζει για την byte stream δύο ιεραρχικές κλάσεις τις : InputStream και OutputStream. Κάτω από αυτές τις κλάσεις υπάρχουν άλλες ιεραρχικά που χειρίζονται τις διαφορετικές συσκευές εισόδου και εξόδου.
• Μέσα στις δύο αυτές κύριες κλάσεις µπορούµε να ορίσουµε πολλές µεθόδους για την επεξεργασία των bytes αλλά οι δύο κυριότερες από αυτές είναι οι :
read() και write().
Οι κλάσεις - Character stream •
Η Java ορίζει για την character stream δύο ιεραρχικές κλάσεις τις : Reader και Writer. Οι δύο αυτές κλάσεις χειρίζονται την δέσµη Unicode που επιτρέπει την διεθνοποίηση των µηνυµάτων των εφαρµογών µας.
•
Μέσα στις δύο αυτές κύριες κλάσεις µπορούµε να ορίσουµε πολλές µεθόδους για την επεξεργασία των χαρακτήρων. Οι δύο πιο κύριες από τις κλάσεις αυτές είναι οι : read() – για το διάβασµα των χαρακτήρων και η
write() – για το γράψιµο των χαρακτήρων .
∆ιάβασµα από την κονσόλα (Input) •
Όλα τα προγράµµατα της Java κάνουν χρήση του πακέτου java.lang. Στο πακέτο αυτό ορίζεται µία σηµαντική κλάση η System που πέρα από τις άλλες σπουδαίες εργασίες που εκτελεί ορίζει και τις παρακάτω µεταβλητές δέσµης : τις in, out και err.
•
Ήδη έχουµε χρησιµοποιήσει την System.out για την εµφάνιση µηνυµάτων και αποτελεσµάτων στην κονσόλα, που εξ ορισµού είναι η οθόνη.
•
Η System.in
χρησιµοποιείται για την στάνταρ είσοδο που είναι το
πληκτρολόγιο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
53
Είσοδος – Έξοδος ( Ι / Ο )
Η System.err χρησιµοποιείται για την στάνταρ δέσµη λαθών που είναι
•
επίσης εξ ορισµού η κονσόλα. •
Για να εισάγουµε χαρακτήρες από το πληκτρολόγιο δηλαδή, ενεργοποιήσουµε την System.in, συνδέουµε το πληκτρολόγιο µε ένα buffer – χαρακτήρων τον
BufferedReader. Ο ορισµός του buffer αυτού γίνεται µε την εντολή: BufferedReader br = Reader(System.in));
•
new
BufferedReader(new
InputStream-
Στον ορισµό: BufferedReader(new InputStreamReader(System.in)) γίνεται η κλήση της υποκλάσης InputStreamReader
που µετατρέπει τα bytes σε
χαρακτήρες. Για να επιτευχθεί αυτή η µετατροπή πρέπει να διασυνδεθεί η δέσµη µε την System.in. •
Το br είναι το τυχαίο όνοµα του BufferedReader και το new, που χρησιµοποιείται
ευρέως στην Java, είναι o τελεστής που δίνει τιµή σε
µεταβλητές κάθε νέου χρησιµοποιούµενου τύπου. •
Στο παρακάτω παράδειγµα θα γίνεται είσοδος χαρακτήρων από το τερµατικό µέχρις ότου εισάγουµε το q.
import java.io.*; class ReadChars { public static void main(String args[])throws IOException { char c; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Input characters, 'q' to quit."); // Είσοδος χαρακτήρων do { c = (char) br.read(); System.out.println(c); } while(c != ‘q’); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
54
Είσοδος – Έξοδος ( Ι / Ο )
Για να διαβάσουµε ένα χαρακτήρα από τον BufferedReader καλούµε την read(). Η έκδοση της read() είναι του τύπου: int read() throws IOException.
•
Με την παραλλαγή αυτή κάθε χαρακτήρας που εισάγεται µετατρέπεται σε αντίστοιχο ακέραιο αριθµό που επιστρέφεται στο πρόγραµµα. Όταν τελειώσει η είσοδος επιστρέφεται η τιµή –1 µε ταυτόχρονη εξαίρεση την IOException.
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα:
Input characters, 'q' to quit. 9876abcdq 9 8 7 6 a b c d q
•
H είσοδος είναι γραµµική και ολοκληρώνεται οριστικά µε το πάτηµα του πλήκτρου Enter.
Άσκηση µε µενού επιλογών •
Στην παρακάτω άσκηση θα κάνουµε χρήση των εντολών switch – do while – break.
class Menu { public static void main(String args[]) throws java.io.IOException { char choice; do { System.out.println("Menu:"); System.out.println("
1. A - choice");
System.out.println("
2. B - choice");
System.out.println("
3. C - choice");
System.out.println("
4. D - choice");
System.out.println("
5. E - choice");
System.out.println("Choose one:");
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
55
Είσοδος – Έξοδος ( Ι / Ο )
choice = (char) System.in.read(); } while( choice < '1' || choice > '5'); System.out.println("\n"); switch(choice) { case '1': System.out.println("A - choice"); System.out.println("Your choice is 1"); break; case '2': System.out.println("B - choice"); System.out.println("Your choice is 2"); break; case '3': System.out.println("C - choice"); System.out.println("Your choice is 3"); break; case '4': System.out.println("D - choice"); System.out.println("Your choice is 4"); break; case '5': System.out.println("E - choice"); System.out.println("Your choice is 5"); break; }
}
}
Είσοδος χαρακτήρων µε χρήση της append •
Στο παρακάτω παράδειγµα θα εισάγουµε χαρακτήρες στο buffer µέχρις ότου πατήσουµε Enter, οπότε και θα εµφανίσουµε τα περιεχόµενα του buffer.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
56
Είσοδος – Έξοδος ( Ι / Ο )
class EisChar { public static void main(String args[]) { StringBuffer s = new StringBuffer(); char c; try { while ((c = (char)System.in.read()) != '\n') { s.append(c); } } catch (Exception e) { System.out.println("Error: " + e.toString()); } System.out.println("Characters "+s); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα:
abcd Characters abcd
Είσοδος String •
Για είσοδο ενός string από το πληκτρολόγιο χρησιµοποιούµε την έκδοση
readLine() που είναι µέλος της κλάσης BufferedReader. H γενική της µορφή είναι : String readLine() throws IOException •
Στο παρακάτω παράδειγµα θα εισάγουµε λέξεις µέχρις ότου εισάγουµε την λέξη Telos.
import java.io.*; class ReadLines { public static void main(String args[]) throws IOException {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
57
Είσοδος – Έξοδος ( Ι / Ο )
// create a BufferedReader using System.in BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Input lines of text."); System.out.println("Input 'Telos' to quit."); do { str = br.readLine(); System.out.println(str); } while(!str.equals("Telos")); } }
Είσοδος αριθµών • Προσέξτε στην παρακάτω άσκηση την µετατροπή των αριθµητικών string στους αντίστοιχους ακέραιους µε την χρήση της : parseInt(). import java.io.*; public class NumInput
{
public static void main(String args[]) throws IOException { int a, b, c; BufferedReader din = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Input number a: "); a = Integer.parseInt(din.readLine()); System.out.println("Input number b: "); b = Integer.parseInt(din.readLine()); c = a + b; System.out.println("a + b = "+c);
} } Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
58
Προγραµµατισµός µε Java
•
Είσοδος – Έξοδος ( Ι / Ο )
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Input number a: 10 Input number b: 20 a + b = 30
•
Να γίνει το πρόγραµµα που διαβάζει πολλούς αριθµούς, τους προσθέτει και τέλος µε την είσοδο του µηδενός εµφανίζει το άθροισµά τους. Το πρόγραµµα κάνει επίσης χρήση της: parseInt(). class ParseDemo { public static void main(String args[]) throws IOException {
// ∆ηµιουργία System.in
του
BufferedReader
InputStream
BufferedReader
br
=
new
χρησιµοποιώνταςτην
BufferedReader(new
Reader(System.in));
String str; int i; int sum=0; System.out.println("Enter numbers, 0 to quit."); do { str = br.readLine(); try { i = Integer.parseInt(str); } catch(NumberFormatException e) { System.out.println("Invalid format"); i = 0; } sum += i; System.out.println("Current sum is: " + sum); } while(i != 0); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
59
Είσοδος – Έξοδος ( Ι / Ο )
Να γίνει το πρόγραµµα που εισάγει ένα συγκεκριµένο πλήθος string (γραµµές κειµένου) για παράδειγµα 100 - γραµµές και τις εµφανίζει µε την είσοδο της λέξης Telos. class KeimenoInput { public static void main(String args[]) throws IOException {
//∆ηµιουργία του BufferedReader χρησιµοποιώνταςτην System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str[] = new String[100];
System.out.println("Input lines of text."); System.out.println("Input 'Telos' to quit."); for(int i=0; i<100; i++) { str[i] = br.readLine(); if(str[i].equals("Telos")) break; } System.out.println("\nHere is your file:"); // Εµφάνιση των γραµµών for(int i=0; i<100; i++) { if(str[i].equals("Telos")) break; System.out.println(str[i]); }
}
}
Μετατροπές εισαγοµένων τιµών • Η µετατροπή ‘αριθµητικού’ string στον αντίστοιχο αριθµό γίνεται µε την κλάση Integer. Η µέθοδος intValue() κάνει την µετατροπή σε Int. Παράδειγµα : String numberOne = "123"; String numberTwo = "456"; // Μετατροπή των αριθµών numberOne, numberTwo σε int µε την Integer
Integer myint1 = Integer.valueOf(numberOne);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
60
Είσοδος – Έξοδος ( Ι / Ο )
Integer myint2 = Integer.valueOf(numberTwo); // Πρόσθεση των δύο αριθµών
int number = myint1.intValue() + myint2.intValue();
Έξοδος στην κονσόλα (Output) •
Οι µέθοδοι print() και println() που έχουµε ήδη χρησιµοποιήσει, ορίζονται από την κλάση PrintStream της System.out που κάνει έξοδο της µορφής byte – ροής.
•
Επειδή η
PrintStream
είναι δέσµη εξόδου που προέρχεται από την
OutputStream περιέχει και την µέθοδο write() που χρησιµοποιείται για την έξοδο στην κονσόλα. Η απλή της µορφή είναι : void •
write(int byteval) throws IOException
Στο παρακάτω παράδειγµα εµφανίζεται ένας χαρακτήρας που εισάγεται µέσα στο πρόγραµµα (o χαρακτήρας Ν) και αφού αλλάξει γραµµή τελειώνει: class WriteDemo { public static void main(String args[]) { char b; b = 'N'; System.out.write(b); System.out.write('\n'); } }
Η κλάση PrintWriter •
Χρησιµοποιείται περισσότερο στις πραγµατικές εφαρµογές από ότι η System.out.
Η δέσµη PrintWriter είναι µία κλάση για έξοδο χαρακτήρων
στην οθόνη.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
61
Είσοδος – Έξοδος ( Ι / Ο )
Υποστηρίζει τις µεθόδους print() και println() για έξοδο όλων των τύπων ακόµη και αντικειµένων. Για να γράψουµε στην οθόνη χρησιµοποιώντας την PrintWriter ορίζουµε πρώτα την System.out για τη δέσµη εξόδου. Η PrintWriter θα οδηγήσει τη δέσµη στην οθόνη µετά από κάθε νέα γραµµή. Μια µορφή της PrintWriter θα µπορούσε να είναι : PrintWriter pw = new PrintWriter(System.out, true);
•
Το παρακάτω παράδειγµα δείχνει την χρήση της PrintWriter για έξοδο στην οθόνη. import java.io.*; public class PrintWriterDemo { public static void main(String args[]) { PrintWriter pw = new PrintWriter(System.out, true); pw.println("This is a string"); int i = -7; pw.println(i); double d = 4.5E-7; pw.println(d); } }
Ασκήσεις εισόδου - επαναλήψεων •
Στο παρακάτω παράδειγµα σε επανάληψη θα προσθέτουµε τους µονούς και ζυγούς αριθµούς ξεχωριστά από το 1 µέχρι µία ανώτατη τιµή που θα εισάγουµε από το πληκτρολόγιο. Τέλος θα εµφανίσουµε τα δύο αυτά επί µέρους αθροίσµατα καθώς και το συνολικό άθροισµα των αριθµών. import java.io.*; class SumOddsEvens {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
62
Προγραµµατισµός µε Java
Είσοδος – Έξοδος ( Ι / Ο )
public static void main (String[] args) throws IOException {
BufferedReader
userin
=
new
BufferedReader
(new
InputStreamReader(System.in)); String inputData; int
N, sumAll = 0, sumEven = 0, sumOdd = 0;
System.out.println( "Enter limit value:" ); inputData = userin.readLine(); N
= Integer.parseInt( inputData );
int count = 0 ; while ( {
count <= N )
sumAll = sumAll + count ; if ( count % 2 == 0
)
sumEven = sumEven + count ; else sumOdd
= sumOdd
+ count ;
count = count + 1 ; } System.out.print
( "Sum of all : " + sumAll
System.out.print
( "\tSum of even: " + sumEven );
System.out.println( "\tSum of odd : " + sumOdd
); );
} }
•
Παραλλαγή της άσκησης είναι να εισάγεται ένα πλήθος αριθµών από το πληκτρολόγιο και να υπολογίζεται ο µέσος όρος τους που θα εµφανίζεται στο τέλος του προγράµµατος.
•
Στην παρακάτω άσκηση θα δούµε πως τερµατίζεται µία θηλιά µε απάντηση από τον χρήστη σε απάντηση ερώτησης του τύπου ‘Continue (y | n) ?’ ή ‘Telos (n | o)’. Στο κύριο µέρος του κώδικα θα γίνεται υπολογισµός του πολυωνύµου : 7x3- 3x2 + 4x – 12. O χρήστης εισάγει µία τιµή για το x και λαµβάνει το αποτέλεσµα του υπολογισµού.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
63
Προγραµµατισµός µε Java •
Είσοδος – Έξοδος ( Ι / Ο )
Η εργασία επαναλαµβάνεται ή τερµατίζει µε την ερώτηση ‘Telos (o | n)’.
import java.io.*; class Polyo {
public static void main (String[] args ) throws IOException {
BufferedReader
userin
=
new
BufferedReader(new
InputStreamReader(System.in) ); String xChars; // Η είσοδος χαρ. Από τον χρήστη double x;
// Ο άγνωστος x του πολυωνύµου
double result; // Το αποτέλεσµα του πολυωνύµου String response = "o";
// "ο" or "n"
while ( response.equals( "o" ) ) {
// Είσοδος του x System.out.println("Enter a value for x:") xChars = userin.readLine() x
;
;
= ( Double.valueOf( xChars ) ).doubleValue();
// Υπολογισµός του πολυωνύµου result =7*x*x*x - 3*x*x + 4*x - 12; // Εµφάνιση του αποτελέσµατος System.out.println("The value of the polynomial at x = " + x + " is :" + result + "\n" ) ; // Συνέχεια ναι | όχι System.out.println("Telos (o | n)?"); response = userin.readLine(); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
64
Προγραµµατισµός µε Java •
Είσοδος – Έξοδος ( Ι / Ο )
Στην παρακάτω άσκηση θα εµφανίσουµε µία λίστα θερµοκρασιών σε βαθµούς Φαρενάϊτ και Κελσίου. Το πρόγραµµα θα κάνει µετατροπές των θερµοκρασιών από την τιµή 0 µέχρι τους 300 βαθµούς Φαρενάϊτ µε βήµα 20 και σύµφωνα µε τη σχέση : C = (5 / 9)(F - 32). class FahrToCelsius
{
public static void main (String args[]) { double fahr, celsius; double lower, upper, step; // αρχική τιµή τις λίστας τιµών Φαρενάϊτ lower = 0.0; // τελική τιµή τις λίστας τιµών Φαρενάϊτ upper = 300.0; // βήµα των µετατροπών step
= 20.0;
fahr = lower; while (fahr <= upper) { celsius = (5.0 / 9.0) * (fahr - 32.0); System.out.println(fahr + " " + celsius); fahr = fahr + step; }
}
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300
-17.7778 -6.66667 4.44444 15.5556 26.6667 37.7778 48.8889 60 71.1111 82.2222 93.3333 104.444 115.556 126.667 137.778 148.889
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
65
Προγραµµατισµός µε Java •
Είσοδος – Έξοδος ( Ι / Ο )
Να γίνει το πρόγραµµα που εµφανίζει ένα πλήθος από αστεράκια για οποιοδήποτε πλήθος γραµµών. Το πλήθος των αστεριών ανά γραµµή καθώς και το πλήθος των γραµµών εµφάνισης θα δίνονται από τον χρήστη. Το πρόγραµµα περιέχει δύο φωλιασµένες while - εντολές. Η εξωτερική θηλιά χειρίζεται τις γραµµές εµφάνισης ενώ η εσωτερική εµφανίζει τα αστεράκια. import java.io.*; class Stars { public static void main (String[] args ) throws IOException { int numRows;
// αριθµός των γραµµών
int numStars;
// αριθµός των αστεριών ανά γραµµή
int row ;
// τρέχον αριθµός γραµµής
int star;
// πλήθος αστεριών για την τρέχουσα γραµµή
BufferedReader userin = new BufferedReader (new InputStreamReader(System.in)); String inputData; // είσοδος δεδοµένων System.out.println( "How many Rows?" ); inputData = userin.readLine(); numRows
= Integer.parseInt( inputData );
System.out.println( "How many Stars per Row?" ); inputData = userin.readLine(); numStars row
=
= Integer.parseInt( inputData ); 1;
while ( row <= numRows ) { star = 1; while ( star <= numStars ) { System.out.print("*"); star = star + 1;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
66
Προγραµµατισµός µε Java
Είσοδος – Έξοδος ( Ι / Ο )
} System.out.println();
// για αλλαγή γραµµής
row = row + 1; } } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : How many Rows? 5 How many Stars per Row? 9 ********* ********* ********* ********* *********
•
Μια παραλλαγή της ανωτέρω άσκησης θα µπορούσε να είναι το πρόγραµµα που ζωγραφίζει ένα χριστουγεννιάτικο δέντρο. * *** ***** ******* ********* *********** ************* *************** *** *** ***
•
Είδαµε σε προηγούµενη άσκηση την απλή είσοδο αριθµών µε την χρήση της parseInt(). Μια άλλη εκδοχή της άσκησης θα ήταν η είσοδος του κάθε αριθµού να γίνεται µε πιο φιλικό προς τον χρήστη τρόπο, για παράδειγµα : Dose ton 1o arithmo (0 gia telos): Dose ton 2o arithmo (0 gia telos):
•
:
:
Στο παρακάτω παράδειγµα θα προσοµοιώσουµε το άνοιγµα µιας ηλεκτρονικής κλειδαριάς. Ο χρήστης θα εισάγει διαδοχικά 3 – αριθµούς και αν είναι σε σωστή σειρά, τότε η κλειδαριά θα ανοίξει.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
67
Είσοδος – Έξοδος ( Ι / Ο )
Λογικό ∆ιάγραµµα
•
Στον παρακάτω κώδικα οι σωστοί αριθµοί θα δίνονται µέσα στο πρόγραµµα.
import java.io.*; class SimulLock { public static void main(String[] args) throws IOException { int lockFirst = 6, lockSecond = 12, lockThird = 30; int numb;
// ο αριθµ. Που εισάγει ο χρήστης
BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String input; boolean correct = true; //Πρώτος αριθµός System.out.println("Enter first number: "); input = stdin.readLine(); numb
= Integer.parseInt( input );
if ( numb != lockFirst ) correct = false ;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
68
Προγραµµατισµός µε Java
Είσοδος – Έξοδος ( Ι / Ο )
//∆εύτερος αριθµός System.out.println("Enter second number: "); input = stdin.readLine(); numb
= Integer.parseInt( input );
if ( numb != lockSecond ) correct = false
;
//Τρίτος αριθµός System.out.println("Enter third number: "); input = stdin.readLine(); numb
= Integer.parseInt( input );
if ( numb != lockThird ) correct = false
;
//Αποτέλεσµα if ( correct ) System.out.println("Lock opens"); else System.out.println("Lock does not open"); } }
•
Στην παρακάτω άσκηση που είναι ένα παιχνίδι εύρεσης της σωστής λέξης µε δύο παίχτες, θα δούµε ένα τρόπο καθαρισµού της οθόνης. Ο καθαρισµός της οθόνης θα γίνει σε µία θηλιά επανάληψης. Στο παιχνίδι ο πρώτος παίχτης εισάγει ‘κρυφά ‘ την λέξη (τουλάχιστον τρεις χαρακτήρες) που θα πρέπει να µαντέψει στη συνέχεια ο δεύτερος παίχτης σε πέντε προσπάθειες. Ο καθαρισµός της οθόνης γίνεται για να µην δει ο δεύτερος παίχτης την λέξη που έγραψε ο πρώτος παίχτης.
import java.io.* ; class Game { public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in ));
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java String
69
Είσοδος – Έξοδος ( Ι / Ο )
theWord;
// Είσοδος της λέξης από τον πρώτο παίχτη. System.out.println("Enter the word to be guessed:"); theWord = stdin.readLine() ; while ( theWord.length() != 3 ) { System.out.println("The word must be three characters long. Please try again."); theWord = stdin.readLine() ; }
// Καθαρισµός της οθόνης
int lineCounter = 0 ; while ( lineCounter < 23 ) { System.out.println(); lineCounter = lineCounter + 1; } // Είσοδος των λέξεων από τον δεύτερο παίχτη. int count = 1; String guess; System.out.println("Enter Your Guess:"); guess = stdin.readLine(); // Πέντε προσπάθειες για σωστή είσοδο από τον δεύτερο παίχτη
while ( count < 6 {
&&
!guess.equals( theWord ) )
System.out.println("Enter Another Guess:"); guess = stdin.readLine(); count
= count + 1;
} // έλεγχος αν νίκησε ο δεύτερος παίχτης. if ( guess.equals( theWord ) ) System.out.println("You Won!"); else System.out.println("You Lost!"); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
70
Είσοδος – Έξοδος ( Ι / Ο )
Ανακατεύθυνση της εξόδου των αποτελεσµάτων •
Με το σύµβολο > ανακατευθύνουµε την έξοδο των αποτελεσµάτων, κατά την εκτέλεση του προγράµµατος, από την οθόνη σε αρχείο κειµένου. Τα αποτελέσµατα του προγράµµατος θα αποθηκευτούν σε αρχείο κειµένου που δηµιουργείται µε την εκτέλεση της εντολής. Παράδειγµα : C:\> java hello > output.txt C:\>
•
Με την µέθοδο αυτή µπορούµε να έχουµε και Ελληνικά µηνύµατα µε την println().
•
Εφόσον το αρχείο που δηµιουργείται είναι αρχείο κειµένου µπορούµε να το εκτυπώσουµε στον εκτυπωτή µέσα από τον κειµενογράφο.
•
Στην ανακατεύθυνση των αποτελεσµάτων δεν αποθηκεύονται τα εισαγόµενα δεδοµένα. Αν θέλουµε αποθήκευση των δεδοµένων εισόδου πρέπει να χρησιµοποιήσουµε την println() µε τα δεδοµένα αυτά. Στο παρακάτω παράδειγµα βλέπουµε την εγγραφή στο αρχείο της τιµής που εισάγουµε : System.out.println("Enter price :"); line = stdin.readLine(); listPrice = Integer.parseInt( line ); System.out.println("Price: " + line ); // Γράψιµο της
εισόδου
Ανακατεύθυνση της εισόδου των δεδοµένων •
Με το σύµβολο δεδοµένα
< ανακατευθύνουµε την είσοδο των δεδοµένων. Τα
κατά την εκτέλεση του προγράµµατος εισάγονται από αρχείο
κειµένου και όχι από το πληκτρολόγιο. Το παρακάτω απλό πρόγραµµα είναι κατασκευασµένο έτσι ώστε να δέχεται την είσοδο των δεδοµένων του χρήστη από το πληκτρολόγιο : Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
71
Είσοδος – Έξοδος ( Ι / Ο )
import java.io.* ; class Redir { public static void main(String[] args) throws IOException { String line; BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Enter your input:"); line = stdin.readLine(); System.out.println( "Input : " + line ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα εµφανιστεί στην οθόνη όποιο κείµενο θα εισάγουµε από το πληκτρολόγιο. Σε δεύτερη φάση φτιάχνουµε ένα αρχείο κειµένου το input.txt µε µία γραµµή κειµένου την: This is the first line of file.
•
Αν αντί για είσοδο από το πληκτρολόγιο κάνουµε ανακατεύθυνση εισόδου από το αρχείο θα εµφανισθεί στην οθόνη απ΄ ευθείας (χωρίς δική µας πληκτρολόγηση) το κείµενο του αρχείου. C:\> java Redir < input.txt
Enter your input: This is the first line of file •
Τι θα γίνει αν το αρχείο εισόδου έχει περισσότερες γραµµές κειµένου; Ασφαλώς θα πρέπει να γίνει θηλιά επανάληψης για το διάβασµα των γραµµών.
import java.io.*; class Redir1 { public static void main(String[] args) throws IOException { String line;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
72
Είσοδος – Έξοδος ( Ι / Ο )
BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); int count = 1; while ( count <= 5 ) { System.out.println("Enter your input" + count + ": "); line = stdin.readLine(); System.out.println( "Input: " + line ); count = count + 1; }
}
}
•
Για να εκτελέσετε το ανωτέρω πρόγραµµα πρέπει να προσθέσετε τις απαιτούµενες γραµµές κειµένου στο αρχείο εισόδου.
Ταυτόχρονη ανακατεύθυνση εισόδου - εξόδου •
Μπορούµε να έχουµε ταυτόχρονη ανακατεύθυνση εισόδου – εξόδου χωρίς να παίζει ρόλο ποια από τις δύο θα προτάξουµε πρώτα : C:\> java Redir < input.txt > output.txt Ή C:\> java Redir > output.txt < input.txt
Είσοδος αριθµών από αρχείο •
Τα δεδοµένα του αρχείου εισόδου µπορεί να είναι αριθµητικά αρκεί να µην περιέχουν κενά διαστήµατα και να έχουν µόνο αριθµητικά ψηφία και τα πρόσηµα + και – . Το παρακάτω πρόγραµµα κάνει απλή είσοδο δύο ακεραίων από το πληκτρολόγιο και αφού τους προσθέσει εµφανίζει το αποτέλεσµα :
import java.io.*; class AddTwoNumbers {
public static void main(String[] args) throws IOException { int numberA, numberB;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
73
Προγραµµατισµός µε Java
Είσοδος – Έξοδος ( Ι / Ο )
String line; BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Enter first number:"); line
= stdin.readLine();
numberA
= Integer.parseInt( line );
System.out.println("Enter second number:"); line
= stdin.readLine();
numberB
= Integer.parseInt( line );
System.out.println( "Sum: " + (numberA + numberB) );
} } •
Αν εκτελέσουµε το πρόγραµµα και εισάγουµε τις τιµές εισόδου θα πάρουµε τα αποτελέσµατα : Enter first number: 25 Enter second number: 5 Sum: 30
•
Το ίδιο αποτέλεσµα θα πάρουµε αν τα δεδοµένα 25 και 5 υπάρχουν σε αρχείο εισόδου, αρκεί να µην έχουµε κενά διαστήµατα : 25
και όχι
5 •
25 5
//µε κενό διάστηµα
Μια λύση για την αποκοπή των κενών διαστηµάτων, είτε στην αρχή είτε στο τέλος ενός string,
είναι η χρήση της µεθόδου trim(). Έτσι το ανωτέρω
παράδειγµα θα µπορούσε να γραφεί πιο σωστά µε την χρήση της trim(): import java.io.*; class AddTwo {
public static void main(String[] args) throws IOException { int numberA, numberB; String line;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
74
Είσοδος – Έξοδος ( Ι / Ο )
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Enter first number:"); line
= stdin.readLine();
numberA
= Integer.parseInt( line.trim() );
System.out.println("Enter second number:");
}
line
= stdin.readLine();
numberB
= Integer.parseInt( line.trim() );
System.out.println( "Sum: " + (numberA + numberB) );
}
•
Οι ίδιοι κανόνες ισχύουν και για είσοδο πραγµατικών αριθµών, είτε αυτή γίνεται από το πληκτρολόγιο είτε µε ανακατεύθυνση από αρχείο.
•
Μια ιδιοµορφία της εντολής for είναι η µεταβλητή επανάληψης να είναι πραγµατικός αριθµός. Το παρακάτω παράδειγµα µας εµφανίζει µια λίστα µε τιµές του x και λογάριθµου του x (ln(x)).
class LogTable { public static void main ( String[] args ) { System.out.println( "x" + "\t ln(x)" );
for ( double x = 0.1; x <= 2.0; x = x + 0.1 ) System.out.println( x + "\t" + Math.log( x ) ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: x
ln(x)
0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999
Παναγιώτης Σφέτσος,
-2.3025850929940455 -1.6094379124341003 -1.203972804325936 -0.916290731874155 -0.6931471805599453 -0.5108256237659907 -0.35667494393873245 -0.22314355131420985 -0.1053605156578264
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
75
Προγραµµατισµός µε Java 0.9999999999999999 1.0999999999999999 1.2 1.3 1.4000000000000001 1.5000000000000002 1.6000000000000003 1.7000000000000004 1.8000000000000005 1.9000000000000006 •
Είσοδος – Έξοδος ( Ι / Ο )
-1.1102230246251565E-16 0.09531017980432474 0.1823215567939546 0.26236426446749106 0.336472236621213 0.40546510810816455 0.47000362924573574 0.5306282510621706 0.5877866649021193 0.641853886172395
Στο παρακάτω παράδειγµα θα κάνουµε είσοδο πραγµατικών αριθµών και θα υπολογίζουµε
και
εµφανίζουµε
την
τετραγωνική
ρίζα
τους.
χρησιµοποιήσουµε την εντολή do – while µε ερώτηση για συνέχεια
Θα ‘
Continue (yes /no)’. import java.io.* ; class NumbersSqrt {
public static void main(String[] args) throws IOException {
String chars; double x; BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in));
do { System.out.print("Enter a number-->"); chars = stdin.readLine(); x
= (Double.valueOf(chars)).doubleValue();
System.out.println("Square root of" + x + " is " + Math.sqrt( x ) ); System.out.print("Continue? (yes or no)-->"); chars = stdin.readLine(); }
while ( chars.equals( "yes" ) );
} }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
76
Είσοδος – Έξοδος ( Ι / Ο )
Μια παραλλαγή της ανωτέρω άσκησης είναι η επίλυσή της µε χρήση της εντολής – while. Προσέξτε την σύνταξη της εντολής αλλά και τι απαιτείται για να ξεκινήσει η επανάληψη.
import java.io.* ; class SqrtCalc { public static void main(String[] args) throws IOException { chars = "yes" ; // Για να αρχίσει η επανάληψη while ( chars.equals( "yes" ) ) { System.out.print("Enter a number-->"); chars = stdin.readLine(); x
= (Double.valueOf(chars)).doubleValue();
System.out.println("Square root of" + x + " is " + Math.sqrt( x ) ); System.out.print("Do you wish to continue?(yes or no)-->"); chars = stdin.readLine(); } } }
•
Για να είµαστε σίγουροι ότι ο χρήστης θα πατήσει το σωστό ‘ναι’ δηλαδή, ‘Υ’, ‘y’, ‘Yes’ ή ‘YES’, τροποποιούµε την while έτσι ώστε να δεχτεί οποιαδήποτε από τις ανωτέρω τιµές.
import java.io.* ; class SqrtCalc { public static void main(String[] args) throws IOException { String chars ; double x; BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); chars = "yes" ; while ( chars.equals( "yes" ) || chars.equals( "YES" ) || chars.equals( "y" ) ||
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
chars.equals( "Y" )
)
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
77
Είσοδος – Έξοδος ( Ι / Ο )
{ System.out.print("Enter a number-->"); chars = stdin.readLine(); x
= (Double.valueOf(chars)).doubleValue();
System.out.println("Square root of " + x + " is " + Math.sqrt( x ) ); System.out.print("Do you wish to continue? (yes or no)->");
chars = stdin.readLine(); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
78
Εξαιρέσεις - Exceptions
Χειρισµός των Εξαιρέσεων •
Η java παρέχει ένα µηχανισµό, τις Εξαιρέσεις (exceptions), που βοηθά το πρόγραµµα να βρει και να χειριστεί τα λάθη. Εξαίρεση (exception) λέγεται ένα συµβάν, συνήθως λάθος, που διακόπτει την ροή εκτέλεσης ενός προγράµµατος.
•
Η εξαίρεση είναι αντικείµενο που προέρχεται άµεσα ή έµµεσα από την κλάση Throwable. Η κλάση αυτή περιέχει δύο υποκλάσεις τις Error και Exception.
•
Για να δηλώσουµε ένα πιθανόν λάθος και να το διορθώσουµε πρέπει πρώτα να το στείλουµε στον κατάλληλο κώδικα και αυτό γίνεται µε την εντολή - throw. Η γενική µορφή της εντολής είναι : throw •
;
H εξαίρεση είναι ένα αντικείµενο που κληρονοµείται άµεσα ή έµµεσα από την κλάση – των Εξαιρέσεων. Η κλάση δείχνει τον τύπο του λάθους, ενώ το αντικείµενο περιέχει ένα λεπτοµερές µήνυµα για το λάθος, όπως για παράδειγµα το που συνέβη.
•
Η throw διακόπτει την φυσική ροή του προγράµµατος και προσπαθεί να βρει ένα χειριστή εξαιρέσεων (exception handler) για τον τύπο της εξαίρεσης που συνέβη. Ο χειριστής εξαιρέσεων είναι ένα κοµµάτι κώδικα που χειρίζεται το ειδικό λάθος που προέκυψε. Ο κώδικας αυτός είτε ανακαλύπτει το λάθος είτε προκαλεί έξοδο από το πρόγραµµα αν αυτό δεν µπορεί να ανακαλυφθεί.
•
Τρεις εντολές χειρίζονται τις εξαιρέσεις οι : try, catch και finally. try { εντολές } catch (όνοµα του τύπου της Εξαίρεσης) { εντολές } catch (όνοµα του τύπου της Εξαίρεσης) { εντολές
:
:
} finally { εντολές }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
79
Εξαιρέσεις - Exceptions
Η εντολή – try περιέχει ένα κοµµάτι κώδικα στο οποίο στέλνεται µία εξαίρεση. Αν συµβεί η εξαίρεση που έχει προβλέψει ο κώδικας της try, τότε µία εντολή – catch µε τον κατάλληλο κώδικα θα χειριστεί τον τύπο της εξαίρεσης. H εντολή – finally, που συνοδεύει πάντα την try, περιέχει ένα κοµµάτι κώδικα που εκτελείται είτε συµβεί λάθος είτε όχι µέσα στην try.
•
Ο παρακάτω κώδικας προκαλεί λάθος (διαίρεση δια του µηδενός) : class Lathos1 { public static void main(String args[]) { int b = 0; int a = 20 / b; } }
•
Επειδή συµβαίνει λάθος στην διαίρεση δηµιουργείται εξαίρεση και το πρόγραµµα τερµατίζει. Επειδή δεν έχουµε προγραµµατίσει κώδικα χειρισµού της εξαίρεσης αναλαµβάνει δράση ο χειριστής εξαιρέσεων της java. Αυτός µε την σειρά του εµφανίζει το µήνυµα της εξαίρεσης καθώς και ένα αντίγραφο της µνήµης στο σηµείο που συνέβη, ενώ παράλληλα τερµατίζει και την εκτέλεση του προγράµµατος.
Exception in thread "main" java.lang.ArithmeticException:/by zero at Lathos1.main(Lathos1.java:4)
•
Για να αποφύγουµε µία τέτοια κατάσταση λάθους θα χρησιµοποιήσουµε µία try – catch εντολή. Με τον τρόπο αυτό θα αποφύγουµε το λάθος και τον απρόσµενο τερµατισµό του προγράµµατος. Στην try γράφουµε τον κώδικα που υποθέτουµε ότι θα προκαλέσει το λάθος και στην catch τον κώδικα που ‘συλλαµβάνει’ το λάθος δηλαδή, τον τύπο της εξαίρεσης που περιµένουµε.
class CatchLathos { public static void main(String args[]) { int a, b; try { // ο κώδικας όπου περιµένουµε το λάθος d = 0; a = 20 / b;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
80
Εξαιρέσεις - Exceptions
System.out.println("This will not be printed."); } catch (ArithmeticException e) { // ‘σύλληψη’του λάθους System.out.println("Division by zero."); } System.out.println("After catch statement."); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα : Division by zero. After catch statement.
•
Μπορούµε να εµφανίσουµε τον τύπο της εξαίρεσης τροποποιώντας την εντολή catch: catch (ArithmeticException e) { System.out.println("Exception: " + e); a = 0; }
•
Μπορούµε να χρησιµοποιήσουµε εστιασµένες try και catch – εντολές.
Throw •
Απόρριψη των εξαιρέσεων µπορούµε να κάνουµε και εµείς, όπως και η java κατά την εκτέλεση του προγράµµατος, χρησιµοποιώντας την εντολή throw. Η εντολή
αυτή
προκαλεί
την προσωρινή
διακοπή
της
εκτέλεσης
του
προγράµµατος. Στην συνέχεια ελέγχονται οι try και catch διαδοχικά µέσα στο πρόγραµµα εάν η εξαίρεση ταιριάζει και έχει προβλεφθεί. Αν η εξαίρεση ταιριάξει µε κάποια εντολή, τότε έχουµε διακλάδωση σε αυτήν. ∆ιαφορετικά αν δεν γίνει διακλάδωση ο έλεγχος µεταβιβάζεται στον αρχικό χειριστή ο οποίος προκαλεί την διακοπή της εκτέλεσης του προγράµµατος και εµφανίζει ένα αντίγραφο της µνήµης για το λάθος.
Finally •
Κάθε try εντολή συνοδεύεται απαραίτητα από µία catch ή finally εντολή. Ο κώδικας της finally εκτελείται πάντα µετά από κάθε try εντολή. Η µόνη
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java περίπτωση
που
δεν
81 εκτελείται
Εξαιρέσεις - Exceptions είναι
να
έχει
προηγηθεί
η
εντολή
System.exit(0)που προκαλεί την έξοδο από το πρόγραµµα. Στο παρακάτω παράδειγµα θα δούµε την χρήση της εντολής finally. class FinallyDemo { static void procA() { try { System.out.println("inside procA"); throw new RuntimeException("demo"); } finally { System.out.println("procA's finally"); }
} static void procB() { try { System.out.println("inside procB"); return; } finally { System.out.println("procB's finally"); }
}
static void procC() { try { System.out.println("inside procC"); } finally { System.out.println("procC's finally"); }
}
public static void main(String args[]) { try { procA(); } catch (Exception e) { System.out.println("Exception caught"); } procB(); procC(); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
82
Εξαιρέσεις - Exceptions
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
inside procA procA's finally Exception caught inside procB procB's finally inside procC procC's finally
•
Στο παρακάτω παράδειγµα θα δούµε µία ακόµη περίπτωση εξαίρεσης και τον χειρισµό της. Το πρόγραµµα κάνει διαδοχικές κλήσεις σε µία διαδικασία για την εκτέλεση πράξεων. Στην πρώτη κλήση η εκτέλεση γίνεται κανονικά, ενώ στην δεύτερη έχουµε διαίρεση δια του µηδενός.
import java.io.* ; import java.lang.Exception ; public class DivideBy0 { public static void main(String[] args) { int a = 2 ; int b = 3 ; int c = 5 ; int d = 0 ; int e = 1 ; int f = 3 ; try
{ System.out.println( a+"/"+b+" = "+div( a, b ) ) ; System.out.println( c+"/"+d+" = "+div( c, d ) ) ; System.out.println( e+"/"+f+" = "+div( e, f ) ) ;
} catch( Exception except ) { System.out.println( "Caught exception " + except.getMessage() ) ;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
}
83
Εξαιρέσεις - Exceptions
}
static int div( int a, int b ) { return (a/b) ; }
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα :
2 / 3 = 0
Caught exception / by zero •
Στο προηγούµενο παράδειγµα η εντολή catch έχει µια γενικότερη µορφή που σηµαίνει ότι µπορεί να χειριστεί περισσότερες κατηγορίες λαθών.
catch( Exception except )
• Το µήνυµα λάθους λαµβάνεται µε την µέθοδο getMessage()της κλάσης Throwable. •
Στο παρακάτω παράδειγµα το πρόγραµµα περιµένει την είσοδο του χρήστη και η εντολή catch δεν κάνει απολύτως τίποτε αν συµβεί κάποια εξαίρεση. Αν ο χρήστης δώσει σωστά δεδοµένα, τότε το πρόγραµµα θα συνεχίσει παρακάτω µε ένα αντίστοιχο µήνυµα.
import java.io.*; public class Try{ public static void main(String args[]){ Try t = new Try(); t.go(); }
//Τέλος της main()
public void go(){ try{ DataInputStream dis= new DataInputStream(System.in); dis.readLine();
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
84
Προγραµµατισµός µε Java
Εξαιρέσεις - Exceptions
} catch(Exception e){ /* η catch δεν κάνει απολύτως τίποτε */ }
//Τέλος της try
System.out.println("ok"); }
//Τέλος της go
} •
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα : 3 ok
•
Στο ανωτέρω παράδειγµα µετά από µία είσοδο εµφανίζεται το µήνυµα ok και το πρόγραµµα τελειώνει. Αν συµβεί εξαίρεση η εντολή catch δεν κάνει καµία απολύτως ενέργεια.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
85
Πίνακες - Arrays
Εισαγωγή Είναι χώροι της µνήµης για προσωρινή αποθήκευση δεδοµένων του ίδιου τύπου. Η επεξεργασία των στοιχείων του πίνακα γίνεται µε εύκολο τρόπο. Η αναφορά στα δεδοµένα κάποιου κελιού του πίνακα γίνεται µε το όνοµα του και ένα ή περισσότερους δείκτες, ανάλογα µε τις διαστάσεις του. Υπάρχουν οι µονοδιάστατοι, δισδιάστατοι και πολυδιάστατοι πίνακες. Σε ένα µονοδιάστατο πίνακα το πρώτο κελί έχει δείκτη µηδέν για παράδειγµα pin[0], το δεύτερο pin[1] και το ν-οστό pin[n].
Ορισµοί και σύνταξη •
Τύπος δεδοµένων < όνοµα - µεταβλητής πίνακα[ ] >;
Όπου: Τύπος δεδοµένων, είναι ο τύπος δεδοµένων των στοιχείων του περιέχει ο πίνακας και είναι ένας από τους γνωστούς τύπους δεδοµένων της java. Το όνοµα της µεταβλητής πίνακα ορίζει το όνοµα του πίνακα. Με τον ορισµό αυτό ορίζεται ένας πίνακας µε µηδενικό περιεχόµενο, δηλαδή ο πίνακας ακόµη δεν υπάρχει στην φυσική του µορφή. Παράδειγµα: int numbers[]; •
<µεταβλητή πίνακα> = new τύπος [µέγεθος];
Όπου: new, είναι ένας τελεστής που δεσµεύει µνήµη για τον πίνακα και θα τον δούµε αναλυτικότερα σε επόµενο κεφάλαιο. Με τον ορισµό αυτό δηµιουργείται πραγµατικά ο πίνακας και ορίζεται το πλήθος των κελιών του. Παράδειγµα: numbers = new int[7]; •
Τύπος δεδοµένων <όνοµα - µεταβλητής πίνακα[ ]> = new τύπος [µέγεθος]; ή
•
Τύπος δεδοµένων[ ] <όνοµα - µεταβλητής πίνακα> = new τύπος [µέγεθος];
Όπου: Ο πλήρης ορισµός του πίνακα µε µία εντολή. Είναι η µορφή που θα χρησιµοποιούµε στις ασκήσεις µας. Παράδειγµα: int numbers[] = new int[7]; ή int[] numbers = new int[7]; Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
86
Πίνακες - Arrays
Παραδείγµατα µε πίνακες numbers[3] = 4; •
Ορίζει την τιµή 4 στο κελί -3 του πίνακα numbers.
numbers[6] = numbers[3]; •
Εκχωρεί το περιεχόµενο του κελιού - 3 στο κελί – 6. Στο παράδειγµα µας τον
αριθµό 4. System.out.println(numbers[6]); •
Εµφανίζει το περιεχόµενο του 6ου – κελιού, δηλαδή τον αριθµό 4.
int numbers[] = {10, 12, 30, 40, 55, 60, 63}; •
Εκχωρεί τιµές στα κελιά του πίνακα δηλαδή: numbers[0] = 10 . . . . numbers[6] = 63
Στο παρακάτω παράδειγµα θα υπολογίσουµε τον µέσο όρο αριθµών που είναι αποθηκευµένα σε πίνακα. class Average { public static void main(String args[]) { double numbers[] = {2.1, 1.2, 4.5, 3.6, 4.7}; double result = 0; int i; for(i=0; i<5; i++) result = result + numbers[i]; System.out.println("Average is " + result / 5); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα: Average is 3.22
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
87
Προγραµµατισµός µε Java
Πίνακες - Arrays
Πίνακες πολλαπλών διαστάσεων •
Για να ορίσουµε µια νέα διάσταση σε πίνακα προσθέτουµε στην εντολή ορισµού του ένα νέο δείκτη µέσα σε τετραγωνικές αγκύλες. Έτσι για να ορίσουµε ένα δισδιάστατο πίνακα προσθέτουµε ένα νέο δείκτη : int Dis[][] = new int[3][4];
•
Ο πίνακας Dis έχει 12 – κελιά. Ο αριστερός δείκτης δείχνει τις γραµµές και ο δεξιός τις στήλες. Μία απεικόνιση του πίνακα θα µπορούσε να είναι:
•
[0] [0]
[0] [1]
[0] [2]
[0] [3]
[1] [0]
[1] [1]
[1] [2]
[1] [3]
[2] [0]
[2] [1]
[2] [2]
[2] [3]
Στο παρακάτω παράδειγµα θα δηµιουργήσουµε ένα τέτοιο πίνακα ( 3 * 4 ) και θα αριθµήσουµε αντίστοιχα το κάθε κελί. Στο τέλος θα εµφανίσουµε τα αποτελέσµατα.
class Dis { public static void main(String args[]) { int Dis[][]= new int[3][4]; int i, j, k = 0; for(i=0; i<3; i++) for(j=0; j<4; j++) { Dis[i][j] = k; k++; } for(i=0; i<3; i++) { for(j=0; j<4; j++) System.out.print(Dis[i][j] + " "); System.out.println(); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
•
88
Πίνακες - Arrays
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
0 1 2 3 4 5 6 7 8 9 10 11 •
Στους πολυδιάστατους πίνακες αρκεί να ορίσουµε τον αριστερό δείκτη – γραµµών ενώ τον δεξιό δείκτη - των στηλών µπορούµε να τον ορίσουµε χειρωνακτικά µέσα στο πρόγραµµα και µε διαφορετική τιµή για κάθε γραµµή. Αυτό σηµαίνει ότι µπορούµε να έχουµε διαφορετικές στήλες σε κάθε γραµµή για ένα πολυδιάστατο πίνακα. ∆ηλαδή, όταν ορίζουµε χειρωνακτικά τις διαστάσεις του πίνακα δεν χρειάζεται να ορίζουµε το ίδιο πλήθος κελιών για κάθε διάσταση. Στο παρακάτω παράδειγµα θα ορίσουµε ένα δισδιάστατο πίνακα στον οποίο τα µεγέθη της δεύτερης διάστασης δεν είναι ίσα.
class Dis1 { public static void main(String args[]) { int Dis1[][] = new int[3][]; Dis1[0] = new int[1]; Dis1[1] = new int[2]; Dis1[2] = new int[3]; int i, j, k = 0; for(i=0; i<3; i++) for(j=0; j
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
89
Προγραµµατισµός µε Java •
Πίνακες - Arrays
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : 0 1 2 3 4 5
•
Στο παρακάτω παράδειγµα θα δηµιουργήσουµε ένα δισδιάστατο πίνακα που θα έχει ως αρχικές τιµές στα κελιά του το γινόµενο των δεικτών του.
class Matrix { public static void main(String args[]) { double m[][] = { { 0*0, 1*0, 2*0, 3*0 }, { 0*1, 1*1, 2*1, 3*1 }, { 0*2, 1*2, 2*2, 3*2 }, { 0*3, 1*3, 2*3, 3*3 } }; int i, j; for(i=0; i<4; i++) { for(j=0; j<4; j++) System.out.print(m[i][j] + " "); System.out.println(); }
}
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
0.0
0.0
0.0
0.0
0.0
1.0
2.0
3.0
0.0
2.0
4.0
6.0
0.0
3.0
6.0
9.0
•
Στο παρακάτω παράδειγµα θα ορίσουµε ένα τρισδιάστατο πίνακα ( 3 * 4 * 5 ) δηλαδή, τρεις δισδιάστατους πίνακες 4 * 5 = 20 κελιών ο καθένας ή διαφορετικά 3 – δισδιάστατους, 4 – γραµµών και 5- στηλών ο καθένας. Το κάθε κελί θα έχει σαν τιµή το γινόµενο των αντιστοίχων δεικτών του.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
90
Πίνακες - Arrays
class Tris { public static void main(String args[]) { int tris[][][] = new int[3][4][5]; int i, j, k; for(i=0; i<3; i++) for(j=0; j<4; j++) for(k=0; k<5; k++) tris[i][j][k] = i * j * k; for(i=0; i<3; i++) { for(j=0; j<4; j++) { for(k=0; k<5; k++) System.out.print(tris[i][j][k] + " "); System.out.println();
}
} System.out.println();
} }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : 00000 00000 00000 00000 00000 01234 02468 0 3 6 9 12 00000 02468 0 4 8 12 16 0 6 12 18 24
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
91
Πίνακες - Arrays
Ο πίνακας είναι ένα αντικείµενο και έχει σαν µέλος την length που
•
ορίζει το πλήθος των κελιών του πίνακα. Έτσι η εντολή if που χρησιµοποιούµε µπορεί να έχει την παρακάτω µορφή : for(int index = 0; index < Dis.length; index++)
•
Στο παρακάτω παράδειγµα εισάγουµε εµείς το πλήθος των κελιών του πίνακα καθώς και τις τιµές των κελιών.
import java.io.* ; class InAr { public static void main ( String[] args ) throws IOException { BufferedReader inData = new BufferedReader(new InputStream Reader(System.in)); int[] array; // εισάγουµε το πλήθος των κελιών System.out.println( "What length is the array?" ); int size array
= Integer.parseInt( inData.readLine() );
= new int[ size ];
// είσοδος των δεδοµένων for ( int index=0; index < array.length; index++) { System.out.println( "Enter an integer: " ); array[ index ] = Integer.parseInt( inData.readLine() ); } // εµφάνιση των αποτελεσµάτων for ( int index=0; index < array.length; index++ ) { System.out.println( "Array[ " + index + " ] = " + array[ index ] ); } } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
92
Πίνακες - Arrays
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
What length is the array? 4 Enter an integer: 10 Enter an integer: 20 Enter an integer: 30 Enter an integer: 40 Array[ 0 ] = 10 Array[ 1 ] = 20 Array[ 2 ] = 30 Array[ 3 ] = 40 •
Το παρακάτω πρόγραµµα βρίσκει και εµφανίζει τη µέγιστη τιµή από τις τιµές ενός πίνακα.
class max1 { public static void main(String[] args) { int[] array = int
{ -20, 19, 1, 5, -1, 27, 19, 5 } ;
max;
// ∆ίνουµε αρχική τιµή στην µεταβλητή max max = array[0]; // Σαρώνουµε τον πίνακα for ( int index=0; index < array.length; index++ ) { if ( array[ index ] > max ) max = array[ index ];
// έλεγχος του τρέχοντος στοιχείου
//Αν είναι µεγαλύτερο άλλαξε το max
} System.out.println("The maximum of this array is: " + max ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
93
Προγραµµατισµός µε Java •
Πίνακες - Arrays
Μια παραλλαγή της ανωτέρω άσκησης είναι να βρεθεί η ελάχιστη τιµή από τις τιµές ενός πίνακα.
Χρήση Πίνακα ως παραµέτρου •
Ένας πίνακας µπορεί να περάσει σαν παράµετρος εισόδου δεδοµένων σε µία µέθοδο. Στο παρακάτω παράδειγµα θα περάσουµε τον πίνακα myarr σαν παράµετρο σε µία µέθοδο print() όπου απλά θα εµφανιστούν τα στοιχεία του πίνακα.
import java.io.*; class AMethod {
void print(int[] x) { for ( int index=0; index < x.length; index++ ) System.out.print( x[index] + " " ); System.out.println(); }
} class MyArrayDemo { public static void main(String[] args) { AMethod operate = new AMethod (); int[] myarr =
{ 14, 1, -21, 13, 8, -7, 35, 80 } ;
System.out.print
("\n The array is : " );
operate.print( myarr ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα :
The array is: 14, 1, -21, 13, 8, -7, 35, 80
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
94
Προγραµµατισµός µε Java
•
Πίνακες - Arrays
Μια παραλλαγή της προηγούµενης άσκησης είναι το πέρασµα στην ίδια µέθοδο ενός δεύτερου πίνακα µε διαφορετικά δεδοµένα.
import java.io.*; class AMethod {
void print(int[] x) { for ( int index=0; index < x.length; index++ ) System.out.print( x[index] + " " ); System.out.println(); }
} class MyArrayDemo { public static void main(String[] args) { AMethod operate = new AMethod (); int[] myarr1 =
{ 14, 1, -21, 13, 8, -7, 35, 80 } ;
int[] myarr2 =
{ 34, 21, 5, 0, 14, 6, 49, 5 } ;
System.out.print
("\n The first array is : " );
operate.print( myarr1 ); System.out.print
("\n The second array is : " );
operate.print( myarr2 ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
The first array is: 14, 1, -21, 13, 8, -7, 35, 80 The second array is: 34, 21, 5, 0, 14, 6, 49, 5
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
95
Προγραµµατισµός µε Java •
Πίνακες - Arrays
Μία παραλλαγή της άσκησης είναι η παρακάτω όπου εµφανίζουµε ένα συγκεκριµένο
πλήθος
στοιχείων
του
πίνακα.
Η
µέθοδος
printRange()δέχεται σαν παραµέτρους τον πίνακα και τις τιµές αρχής και
τέλους εµφάνισης. import java.io.*; class AMethod {
void print( int[] x ) { for ( int index=0; index < x.length; index++ ) System.out.print( x[index] + " " ); System.out.println(); } // εµφάνιση των στοιχείων από τιµή-start µέχρι-end. void printRange ( int[] x, int start, int end ) {
for ( int index=start; index <= end ; index++ ) System.out.print( x[index] + " " ); System.out.println();
} } class MyArrayDemo { public static void main(String[] args) { AMethod operate = new AMethod(); int[] myarr1 =
{ 14, 1, -21, 13, 8, -7, 35, 80 } ;
// εµφάνιση πέντε στοιχείων των: 1, -21, 13, 8, -7. operate.printRange( myarr1, 1, 5 ); } }
•
Μία βελτιωµένη παραλλαγή της εντολής if είναι:
for (int index=start; index < end && index >= 0 && index < x.length; index++)
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
96
Πίνακες - Arrays
Μία µέθοδος της βιβλιοθήκης java.lang είναι η arraycopy() .Η σύνταξη της εντολής είναι: static
void
arraycopy(,
sourceStart>,
, ,);
Όπου: ,
Ο πίνακας που θα αντιγράψουµε.
,
Από ποιο στοιχείο θα αρχίσει η αντιγραφή ;
,
Ο πίνακας αντίγραφο.
,
Από ποιο στοιχείο του αντιγράφου θα αρχίσει η αντιγραφή ; Πόσα στοιχεία θα αντιγράψει.
);
•
Στο παρακάτω απλό παράδειγµα θα δούµε την χρήση της arraycopy(). public class ArrayCopyDemo { public static void main(String[] args) { int ar[] = {0,0,0,0,0,0,0,0,0,0}; for (int i = 0; i < 10; ++i) { System.arraycopy(ar,0,ar,1,9); ar[0] = i; } System.out.print("ar = "); for (int i = 0; i < 10; ++i) { System.out.print(ar[i] + " "); } System.out.println(""); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : ar = 9 8 7 6 5 4 3 2 1 0
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
97
Κλάσεις - Αντικείµενα
Κλάσεις Η κλάση ορίζει ένα νέο τύπο δεδοµένων. Είναι το πρότυπο από το οποίο δηµιουργούνται τα αντικείµενα. Με τον ορισµό µιας κλάσης ορίζονται τα δεδοµένα που θα εµπεριέχει καθώς και ο κώδικας που θα τα χειρίζεται.
Ορισµός της Κλάσης Μία κλάση ορίζεται µε την χρήση της δεσµευµένης λέξης class. Η γενική µορφή του ορισµού της κλάσης είναι: class <όνοµα κλάσης> { type instance – µεταβλητή-1 type instance – µεταβλητή-2 : : : type instance – µεταβλητή-n type <όνοµα-µεθόδου-1> //σώµα της µεθόδου } type <όνοµα-µεθόδου-2> //σώµα της µεθόδου } : : type <όνοµα-µεθόδου-n> //σώµα της µεθόδου }
(λίστα παραµέτρων) { (λίστα παραµέτρων) { : (λίστα παραµέτρων) {
} Τα δεδοµένα ή µεταβλητές που ορίζονται µέσα σε µία κλάση ονοµάζονται ‘περιστασιακές’ µεταβλητές (instance variables), ενώ ο κώδικας
- µέθοδοι
(methods). Οι µεταβλητές και οι µέθοδοι ονοµάζονται µαζί µέλη της κλάσης (members). Οι µεταβλητές της κλάσης ονοµάζονται ‘περιστασιακές’ διότι κάθε ‘περίσταση’ κλάσης περιέχει το δικό της αντίγραφο από αυτές τις µεταβλητές. Περιστάσεις της κλάσης είναι στην πραγµατικότητα τα αντικείµενα (objects) της κλάσης. Εποµένως τα δεδοµένα κάθε αντικειµένου είναι µοναδικά και διαφορετικά από τα δεδοµένα άλλων αντικειµένων. Οι κλάσεις της java δεν περιέχουν υποχρεωτικά την µέθοδο main() και η ειδική κατηγορία προγραµµάτων applets δεν χρειάζεται καθόλου την main(). Μία κλάση περιέχει τη µέθοδο main() όταν από Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
98
Κλάσεις - Αντικείµενα
αυτήν ξεκινά το πρόγραµµα. Στις µικρές εφαρµογές η main() είναι συνήθως και η µοναδική µέθοδος. Στις µεγαλύτερες εφαρµογές η main() δηµιουργεί αντικείµενα και χρησιµοποιεί τις µεθόδους των. •
Στο παρακάτω παράδειγµα θα δούµε αναλυτικά τον ορισµό κλάσεων, αντικειµένων, µεταβλητών και µεθόδων. Θα δούµε επίσης πως καλούµε µία µέθοδο. class Box { double width; double height; double depth; // µέθοδος για εµφάνιση του όγκου του κουτιού. void volume() { System.out.print("Volume is "); System.out.println(width * height * depth);
}
}
class BoxDemo { public static void main(String args[]) { Box mybox1 = new Box();
//δηµιουργία του αντικειµένου1
Box mybox2 = new Box();
//δηµιουργία του αντικειµένου2
// δίνουµε τιµές στο αντικείµενο mybox1 mybox1.width = 10; mybox1.height = 20; mybox1.depth = 15; // δίνουµε διαφορετικές τιµές στο αντικείµενο mybox2 mybox2.width = 3; mybox2.height = 6; mybox2.depth = 9; // εµφάνιση του όγκου του 1ου κουτιού. mybox1.volume(); // εµφάνιση του όγκου του 2ου κουτιού. mybox2.volume(); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
99
Κλάσεις - Αντικείµενα
Πρώτα δηµιουργούµε την κλάση box µε τρεις µεταβλητές τις width, height και depth. class Box { double width; double height; double depth;
}
Ορισµός των αντικειµένων – Τελεστής new •
Μετά τον ορισµό της κλάσης µπορούµε να ορίσουµε αντικείµενα της κλάσης. Εδώ ορίζουµε δύο αντικείµενα του τύπου box. Η δηµιουργία των αντικειµένων γίνεται µε τον τελεστή new ο οποίος δεσµεύει δυναµικά µνήµη για το αντικείµενο.
•
Box mybox1 = new Box();
//δηµιουργία του αντικειµένου1
Box mybox2 = new Box();
//δηµιουργία του αντικειµένου2
Ο ορισµός των αντικειµένων ακολουθεί ουσιαστικά δύο βήµατα: τον ορισµό της µεταβλητής που αναφέρεται (referenced) στο αντικείµενο και τη φυσική καταχώρηση του αντικειµένου στη µεταβλητή µε την αντίστοιχη δέσµευση µνήµης. Στο παράδειγµά µας αναλυτικότερα η δηµιουργία του αντικειµένου θα µπορούσε να γίνει µε τις δύο παρακάτω εντολές: (1) Box
mybox1;
(2)
mybox1=new
Box(); •
Στην (1) η mybox1 έχει τιµή µηδέν (null), ενώ στην (2) η mybox1 κρατά την διεύθυνση της µνήµης του αντίστοιχου αντικειµένου Box.
•
Στην συνέχεια δίνουµε διαφορετικές τιµές στις µεταβλητές των δύο αντικειµένων mybox1 και mybox2.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
100
Κλάσεις - Αντικείµενα
Ορισµός των Μεθόδων •
Συντάσσουµε την µέθοδο volume() η οποία εδώ απλώς θα εµφανίσει τον όγκο των αντικειµένων mybox1 και mybox2. Η µέθοδος αυτή είναι µέλος της κλάσης Box και για τον λόγο αυτό γράφεται µέσα στο σώµα της. void volume() { System.out.print("Volume is "); System.out.println(width * height * depth); }
•
Η γενική µορφή µιας µεθόδου είναι:
type <όνοµα> (Λίστα παραµέτρων) { //σώµα της µεθόδου } Όπου type,είναι οποιοσδήποτε υπάρχον τύπος δεδοµένων ή δικός µας. Λίστα παραµέτρων είναι µεταβλητές χωρισµένες µε κόµµα που λαµβάνουν τις τιµές που στέλνουµε σαν ορίσµατα µε την κλήση της µεθόδου. Αν δεν έχουµε κλήση µε παραµέτρους, η Λίστα παραµένει άδεια. Όταν η µέθοδος δεν επιστρέφει κάποια τιµή, τότε συντάσσουµε την void, ενώ όταν επιστρέφει τιµή συντάσσουµε την: return <τιµή>; •
Η κλήση της µεθόδου volume() γίνεται µε τις εντολές : mybox1.volume(); mybox2.volume();
Προσέξτε την χρήση της τελείας (dot) που προσδιορίζει το αντικείµενο στο οποίο αναφερόµαστε. Στο παράδειγµα η volume() εµφανίζει τον όγκο των δύο αντικειµένων. Η ίδια µέθοδος εµφανίζει διαφορετικά αποτελέσµατα για τα δύο διαφορετικά αντικείµενα (διαφορετικές δεδοµένα). Όταν µεταγλωττίσουµε το
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
101
Κλάσεις - Αντικείµενα
πρόγραµµα θα δηµιουργηθούν δύο αρχεία µε κατάληξη .class, τα Box.class και BoxDemo.class. Η java τοποθετεί την κάθε κλάση σε ξεχωριστό αρχείο. Θα µπορούσαµε να γράψουµε και εµείς τον κώδικα σε δύο ξεχωριστά πηγαία αρχεία µε κατάληξη .java, τα Box.java και BoxDemo.java. Η εκτέλεση του προγράµµατος γίνεται µε την κλήση της BoxDemo. class.
Επιστροφή τιµής Μεθόδου •
Στο παρακάτω παράδειγµα θα τροποποιήσουµε την µέθοδο volume() καθώς και τις εντολές κλήσης της έτσι ώστε να πάρουµε σαν επιστρεφόµενη τιµή τον όγκο του κάθε αντικειµένου box.
class Box { double width; double height; double depth; // υπολογισµός και επιστροφής της τιµής
double volume() { return width * height * depth;
} } class BoxDemo1 { public static void main(String args[]) { Box mybox1 = new Box(); Box mybox2 = new Box(); double vol; // δίνουµε τιµές στις µεταβλητές του mybox1 mybox1.width = 10; mybox1.height = 20; mybox1.depth = 15; // δίνουµε τιµές στις µεταβλητές του mybox2 mybox2.width = 3; mybox2.height = 6;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
102
Κλάσεις - Αντικείµενα
mybox2.depth = 9; // λαµβάνουµε την τιµή για το πρώτο αντικείµενο vol = mybox1.volume(); System.out.println("Volume is " + vol); // λαµβάνουµε την τιµή για το δεύτερο αντικείµενο vol = mybox2.volume(); System.out.println("Volume is " + vol); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα ίδια αποτελέσµατα :
Volume is Volume is •
3000.0 162.0
Προσέξτε την κλήση της µεθόδου : vol = mybox1.volume(); vol = mybox2.volume();
Στο παράδειγµα η µεταβλητή vol είναι αυτή που θα λάβει το αποτέλεσµα της µεθόδου volume(). Προσοχή ! Η µεταβλητή που θα λάβει το αποτέλεσµα πρέπει να είναι του ίδιου τύπου µε το επιστρεφόµενο από την µέθοδο. Η λήψη της επιστρεφόµενης τιµής µπορεί να γίνει και απ’ ευθείας µε την εντολή εµφάνισης του αποτελέσµατος : System.out.println(“Volume is “ + mybox1.volume());
Μέθοδοι που δέχονται παραµέτρους •
Είναι η πιο σηµαντική µορφή χρήσης µιας µεθόδου. Έστω ότι η µέθοδος προσθέτει δύο αριθµούς και επιστρέφει το άθροισµά των. Μία µορφή της µεθόδου θα ήταν :
int sum( int x, int y) { return x + y ; } Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
103
Κλάσεις - Αντικείµενα
Η κλήση στην µέθοδο θα είχε για παράδειγµα την µορφή : z = sum(3, 5); Το αποτέλεσµα που θα επέστρεφε η µέθοδος θα ήταν ο ακέραιος αριθµός 8. Η µεταβλητή z θα πρέπει να είναι του τύπου int. Την παραµετροποίηση στο πέρασµα των τιµών θα δούµε στο παρακάτω παράδειγµα. Στο παράδειγµα θα φτιάξουµε την µέθοδο sizeofBox που θα δίνει τιµή στις τρεις µεταβλητές. Οι τιµές θα περάσουν στην µέθοδο µε την χρήση παραµέτρων. class Box { double width; double height; double depth; // υπολογισµός και επιστροφή του όγκου double volume() { return width * height * depth; } // ορίζει τις διαστάσεις του box.
void sizeofBox(double x, double y, double z) { width
}
=
x;
height =
y;
depth
z;
=
}
class BoxDemo2 { public static void main(String args[]) { Box mybox1 = new Box(); Box mybox2 = new Box(); double vol; // αρχικοποίηση τιµών για κάθε box
mybox1.sizeofBox(9, 8, 3); mybox2.sizeofBox(14, 13, 12); vol = mybox1.volume(); System.out.println("Volume is " + vol); vol = mybox2.volume(); System.out.println("Volume is " + vol); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
104
Κλάσεις - Αντικείµενα
Τις τιµές 9, 8 και 3 λαµβάνουν αντίστοιχα οι µεταβλητές width, height και depth για το πρώτο αντικείµενο box και τις τιµές 14, 13 και 12 για το δεύτερο αντικείµενο.
∆οµητές - Constructors Ο συντοµότερος και αποτελεσµατικότερος τρόπος αρχικοποίησης των µεταβλητών είναι να γίνεται κατά την στιγµή της δηµιουργίας του αντικειµένου και όχι µε τον τρόπο που είδαµε στο προηγούµενο παράδειγµα. Η java επιτρέπει την αυτόµατη αρχικοποίηση των αντικειµένων κατά τη στιγµή της δηµιουργίας των µε την χρήση του δοµητή (constructor). Ο δοµητής αρχικοποιεί αµέσως το αντικείµενο κατά την στιγµή της δηµιουργίας του, έχει το ίδιο όνοµα µε το όνοµα της κλάσης στην οποία ανήκει το αντικείµενο και συντάσσεται µε τον ίδιο τρόπο όπως της µεθόδου. Ο δοµητής καλείται λίγο πριν την ολοκλήρωση της new. •
Στο παρακάτω παράδειγµα θα τροποποιήσουµε τον κώδικα της sizeofBox ώστε να γίνει ένας δοµητής που θα αρχικοποιεί τις µεταβλητές του αντικειµένου. class Box { double width; double height; double depth; // ο δοµητής του Box. Box() { System.out.println("Constructing Box"); width = 10; height = 10; depth = 10; } // υπολογισµός και επιστροφή του όγκου double volume() { return width * height * depth; } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
105
Κλάσεις - Αντικείµενα
class BoxDemo3 { public static void main(String args[]) { // declare, allocate, and initialize Box objects Box mybox1 = new Box(); Box mybox2 = new Box(); double vol; // λαµβάνεται ο όγκος του πρώτου box vol = mybox1.volume(); System.out.println("Volume is " + vol); // λαµβάνεται ο όγκος του δευτέρου box vol = mybox2.volume(); System.out.println("Volume is " + vol); } }
•
Ο δοµητής δεν επιστρέφει τιµή µε την return ούτε χρησιµοποιούµε την void.
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα: Constructing
Box
Constructing
Box
Volume is 1000.0 Volume is 1000.0 •
Στο ανωτέρω παράδειγµα ο δοµητής αρχικοποιεί και τα δύο αντικείµενα µε τις ίδιες τιµές. Για να έχουµε διαφορετικές τιµές για τα δύο αντικείµενα όπως είναι το σωστό, παραµετροποιούµε τον δοµητή. Ο παρακάτω κώδικας αποτελεί µία τέτοια παραλλαγή.
class Box { double width; double height; double depth;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
106
Κλάσεις - Αντικείµενα
// O δοµητής της Box. Box(double x, double y, double z) { width = x; height = y; depth = z; } // υπολογισµός και επιστροφή του όγκου double volume() { return width * height * depth; }
} class BoxDemo4 { public static void main(String args[]) { // δήλωση, και αρχικοποίηση των αντικειµένων box. Box mybox1 = new Box(10, 20, 15); Box mybox2 = new Box(3, 6, 9); double vol; // λήψη όγκου του πρώτου box vol = mybox1.volume(); System.out.println("Volume is " + vol); // λήψη όγκου του δευτέρου box vol = mybox2.volume(); System.out.println("Volume is " + vol); }
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα ίδια αποτελέσµατα :
Volume is Volume is
3000.0 162.0
Η δεσµευµένη λέξη - this Χρησιµοποιείται µέσα σε µεθόδους όταν γίνεται αναφορά στο τρέχον αντικείµενο της µεθόδου. Ο δοµητής box() θα µπορούσε να γραφεί: Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
107
Κλάσεις - Αντικείµενα
Box(double x, double y, double z) { this.width = x; this.height = y; this.depth = z; }
Αν οι µεταβλητές των αντικειµένων έχουν το ίδιο όνοµα µε τις τοπικές µεταβλητές, τότε υπερισχύουν οι τοπικές µεταβλητές και ‘κρύβουν’ τις τιµές των µεταβλητών των αντικειµένων. Στις περιπτώσεις αυτές χρησιµοποιούµε και πάλι την this : Box(double width, double height, double depth) { this.width = width; this.height = height; this.depth = depth; }
Συλλογή σκουπιδιών (Garbage collection) Η java διαγράφει αυτόµατα τα αντικείµενα που δεν χρησιµοποιούνται και ελευθερώνει την µνήµη που καταλαµβάνουν. Η τεχνική αυτή ονοµάζεται ‘συλλογή σκουπιδιών’. Η τεχνική αυτή λειτουργεί ως εξής : όταν µέσα στο πρόγραµµα δεν υπάρχει κάποια αναφορά σε κάποιο αντικείµενο, τότε θεωρείται ότι το αντικείµενο δεν χρειάζεται πλέον και διαγράφεται.
Η µέθοδος Finalize() Είναι η µέθοδος που χρησιµοποιείται όταν πριν από την διαγραφή ενός αντικειµένου απαιτείται η εκτέλεση κάποιων άλλων εργασιών. Η java πριν την διαγραφή ενός αντικειµένου καλεί την µέθοδο αυτή και εκτελεί τον κώδικα που βρίσκεται στο σώµα της finalize(). Η γενική µορφή της µεθόδου είναι : protected void finalize() { // κώδικας της µεθόδου } Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
108
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
Η δεσµευµένη λέξη protected χρησιµοποιείται για να µην µπορεί να προσπελαθεί ο κώδικας της finalize() από κώδικα εξωτερικά της κλάσης.
Έλεγχος Προσπέλασης (Access control) Τρεις δεσµευµένες λέξεις που χρησιµοποιούµε για τους ορισµούς των µελών µιας κλάσης επιτρέπουν ή απαγορεύουν την προσπέλαση οι : public, private και protected. Η protected αφορά την κληρονοµικότητα (χρήση σε µεθόδους). Η public επιτρέπει την προσπέλαση από κώδικα έξω από την κλάση. Η main() ορίζεται πάντα public για να καλείται και έξω από το πρόγραµµά δηλαδή, από το σύστηµα run-time της java. Κάθε ορισµός που δεν περιλαµβάνει ένα από τους ανωτέρω ελέγχους θεωρείται public. Η private επιτρέπει την προσπέλαση σε άλλα µέλη της κλάσης και αποτρέπει την προσπέλαση έξω από αυτήν. Στο παρακάτω παράδειγµα θα δούµε την χρήση του ελέγχου προσπέλασης και τις διαφορές µεταξύ public και private. class Test { int a;
// χωρίς δήλωση, άρα public
public int b;
// public προσπέλαση
private int c;
// private προσπέλαση
// µέθοδοι για προσπέλαση της c void setc(int i) {
// ορισµός της τιµής της c
c = i; } int getc() {
// λήψη της τιµής της c
return c; } } class AccessTest { public static void main(String args[]) { Test ob = new Test(); // Οι a και b µπορούν να προσπελαθούν απ’ ευθείας ob.a = 10; ob.b = 20;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
109
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
// ο παρακάτω ορισµός είναι λάθος //
ob.c = 100;
//λάθος στην προσπέλαση
// προσπέλαση στη c µόνο µέσω της µεθόδου της ob.setc(100);
// OK
System.out.println("a, b, and c: " + ob.a + " " + ob.b + " " + ob.getc()); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : a, b, and c : 10
•
20
100
Η c δεν µπορεί να προσπελαθεί από κώδικα έξω από την κλάση της, αλλά µόνο µέσα από τις public – µεθόδους setc() και getc().
•
Ένα άλλο παράδειγµα µε ελέγχους στα µέλη της κλάσης είναι η προσοµοίωση της µνήµης stack. Η µνήµη αυτή αποθηκεύει τα δεδοµένα µε τη µέθοδο first in – last out δηλαδή, όποιο δεδοµένο µπαίνει πρώτο – βγαίνει τελευταίο, όπως όταν στοιβάζουµε πιάτα επάνω σε ένα τραπέζι. Η µνήµη αυτή ελέγχεται µε δύο λειτουργίες που παραδοσιακά ονοµάζονται push και pop. Η push για να βάλουµε ένα στοιχείο στην κορυφή της στοίβας και η pop για να βγάλουµε ένα στοιχείο από την στοίβα. Στο παράδειγµα θα προσοµοιώσουµε την stack για χειρισµό ακεραίων :
class Stack { private int stck[] = new int[10]; private int tos; //αρχικοποίηση της κορυφής της stack στον δοµητή //stack(). Σε άδεια stack η τιµή της tos = -1. Stack() { tos = -1; }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
110
Κλάσεις - Αντικείµενα
// Βάλε ένα στοιχείο στη stack void push(int item) { if(tos==9) System.out.println("Stack is full."); else stck[++tos] = item; } // Βγάλε ένα στοιχείο από την stack int pop() { if(tos < 0) { System.out.println("Stack underflow."); return 0; } else return stck[tos--]; } }
•
Η παρακάτω κλάση – TestStack θα ελέγξει την κλάση stack χρησιµοποιώντας δύο πίνακες µε 10 – ακεραίους ο καθένας.
class TestStack { public static void main(String args[]) { Stack mystack1 = new Stack(); Stack mystack2 = new Stack(); // βάλε µερικούς αριθµ. στη stack for(int i=0; i<10; i++) mystack1.push(i); for(int i=10; i<20; i++) mystack2.push(i); // βγάλε µερικούς αριθµ. Από τη stack System.out.println("Stack in mystack1:"); for(int i=0; i<10; i++) System.out.println(mystack1.pop()); System.out.println("Stack in mystack2:"); for(int i=0; i<10; i++) System.out.println(mystack2.pop());
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
111
Κλάσεις - Αντικείµενα
// Οι παρακάτω εντολές δεν δουλεύουν // mystack1.tos = -2; // mystack2.stck[3] = 100; } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Stack in mystack1: 9 8 7 6 5 4 3 2 1 0 Stack in mystack2: 19 18 17 16 15 14 13 12 11 10
•
Στην ανωτέρω άσκηση ορίσαµε τον πίνακα stck και τoν δείκτη της κορυφής της stack, την tos, ως private. Αυτό σηµαίνει ότι δεν µπορούν να προσπελαθούν παρά µόνο µέσα από τις push() και pop(). private int stck[] = new int[10]; private int tos;
Μέθοδοι Υπερφόρτωσης (Overloading Methods) Στη java είναι δυνατόν να ορίσουµε µέσα σε µία κλάση δύο ή περισσότερες µεθόδους µε το ίδιο όνοµα αλλά µε διαφορετικές παραµέτρους. Αυτό ονοµάζεται υπερφόρτωση µεθόδων και στην περίπτωση αυτή ο τύπος των δεδοµένων και ο αριθµός των παραµέτρων λαµβάνονται υπ’ όψιν στον προσδιορισµό της µεθόδου
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
112
Κλάσεις - Αντικείµενα
που θα εκτελεσθεί. Στο παρακάτω παράδειγµα θα δούµε πως υλοποιείται η υπερφόρτωση µεθόδων. class OverloadDemo { void test() { System.out.println("No parameters"); } // υπερφόρτωση µε µία integer παράµετρο. void test(int a) { System.out.println("a: " + a); } // υπερφόρτωση µε δύο integer παραµέτρους. void test(int a, int b) { System.out.println("a and b: " + a + " " + b); } // υπερφόρτωση µε µία double παράµετρο. double test(double a) { System.out.println("double a: " + a); return a*a; } } class Overload { public static void main(String args[]) { OverloadDemo ob = new OverloadDemo(); double result; // κλήση όλων των παραλαγών της test() ob.test(); ob.test(10); ob.test(10, 20); result = ob.test(123.2); System.out.println("Result of ob.test(123.2): " + result); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
113
Κλάσεις - Αντικείµενα
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
No parameters a: 10 a and b: 10 20 double a: 123.2 Result of ob.test(123.2): 15178.240000000002 •
Για την επιλογή της κατάλληλης µεθόδου η java µπορεί να κάνει και αυτόµατη µετατροπή τύπου δεδοµένων. Στο παρακάτω παράδειγµα θα κάνει µετατροπή του τύπου integer σε double έτσι ώστε να γίνει η κλήση της κατάλληλης µεθόδου.
class OverloadDemo { void test() { System.out.println("No parameters"); } // υπερφόρτωση µε δύο integer παραµέτρους. void test(int a, int b) { System.out.println("a and b: " + a + " " + b); } // υπερφόρτωση µε double παράµετρο. void test(double a) { System.out.println("Inside test(double) a: " + a); } } class Overload { public static void main(String args[]) { OverloadDemo ob = new OverloadDemo(); int i = 88; ob.test(); ob.test(10, 20); ob.test(i); // θα καλέσει την test(double). Παράδοξο; ob.test(123.2); // θα καλέσει την test(double) } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
114
Κλάσεις - Αντικείµενα
Στο ανωτέρω παράδειγµα επειδή δεν υπάρχει µέθοδος test(int) η java µετατρέπει τον τύπο integer σε double και καλεί µε υπερφόρτωση την κατάλληλη µέθοδο που είναι η test(double).
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
No parameters a and b: 10 20 Inside test(double) a: 88.0 Inside test(double) a: 123.2
Υπερφόρτωση ∆οµητών Υπερφόρτωση µπορεί να εφαρµοσθεί και στους δοµητές όπως και στις απλές µεθόδους. Για παράδειγµα, κατά τον ορισµό του αντικειµένου box θα συµβεί υπερφόρτωση δοµητών αν χρησιµοποιήσουµε διαφορετικές παραµέτρους. Στο παρακάτω
παράδειγµα θα δούµε πως µπορεί συµβεί υπερφόρτωση όταν ο
ορισµός του αντικειµένου box µπορεί να γίνει µε την χρήση διαφορετικών δοµητών. class Box { double width; double height; double depth; // δοµητής που χρησιµοποιείται για όλες τις διαστάσεις Box(double w, double h, double d) { width = w; height = h; depth = d; } //δοµητής όταν δεν ορίζουµε κάποια διάσταση //χρησιµοποιούµε τις τιµές –1 Box() { width = -1; height = -1; depth = -1;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
115
Κλάσεις - Αντικείµενα
} // δοµητής που χρησιµοποιείται όταν ορίζεται το box. Box(double len) { width = height = depth = len; } // υπολογισµός και επιστροφή του όγκου double volume() { return width * height * depth; } } class OverloadCons { public static void main(String args[]) { // δηµιουργία του box µε διαφορετικούς δοµητές. Box mybox1 = new Box(10, 20, 15); Box mybox2 = new Box(); Box mycube = new Box(7); double vol; // λήψη του όγκου του 1ου box. vol = mybox1.volume(); System.out.println("Volume of mybox1 is " + vol); // λήψη του όγκου του 2ου box. vol = mybox2.volume(); System.out.println("Volume of mybox2 is " + vol); // λήψη του όγκου του κύβου. vol = mycube.volume(); System.out.println("Volume of mycube is " + vol); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Volume of mybox1 is 3000.0 Volume of mybox1 is –1.0 Volume of mybox1 is 343.0
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
116
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
Αντικείµενα σαν παράµετροι Αντί για τους απλούς τύπους δεδοµένων µπορούµε να χρησιµοποιήσουµε αντικείµενα σαν παραµέτρους τόσο στις µεθόδους όσο και στους δοµητές. Μία συνηθισµένη περίπτωση είναι εκείνη όπου ορίζεται ένα αντικείµενο από ένα ήδη υπάρχον. Στην περίπτωση αυτή χρησιµοποιείται δοµητής που δέχεται σαν παράµετρο ένα ήδη υπάρχον αντικείµενο. Στην παρακάτω παραλλαγή του παραδείγµατος box θα δούµε πως ένα αντικείµενο ορίζει ένα άλλο. class Box { double width; double height; double depth; // δηµιουργία κλώνου αντικειµένου Box(Box ob) {
// πέρασµα αντικειµένου στον δοµητή
width = ob.width; height = ob.height; depth = ob.depth; } // δοµητής όταν γνωρίζουµε όλες τις διαστάσεις. Box(double w, double h, double d) { width = w; height = h; depth = d; } // δοµητής όταν δεν καθορίζονται διαστάσεις. Box() { width = -1; height = -1; depth = -1; } // δοµητής που χρησιµοποιείται όταν ορίζεται ο κύβος. Box(double len) { width = height = depth = len; }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
117
Κλάσεις - Αντικείµενα
// υπολογισµός και επιστροφή του όγκου. double volume() { return width * height * depth; }
}
class OverloadCons2 { public static void main(String args[]) { // δηµιουργία διαφορετικών αντικειµένων. Box mybox1 = new Box(10, 20, 15); Box mybox2 = new Box(); Box mycube = new Box(7); Box myclone = new Box(mybox1); double vol; // λήψη του όγκου του 1ου box. vol = mybox1.volume(); System.out.println("Volume of mybox1 is " + vol); // λήψη του όγκου του 1ου box. vol = mybox2.volume(); System.out.println("Volume of mybox2 is " + vol); // λήψη του όγκου του κύβου. vol = mycube.volume(); System.out.println("Volume of cube is " + vol); // λήψη του όγκου του κλώνου. vol = myclone.volume(); System.out.println("Volume of clone is " + vol); } }
Μια δεύτερη µατιά στο πέρασµα των παραµέτρων Οι παράµετροι που χρησιµοποιούνται κατά την κλήση µιας υπορουτίνας, ανάλογα µε την χρήση των, ονοµάζονται είτε παράµετροι τιµής (call – by - value) είτε παράµετροι αναφοράς (call – by – reference).
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
118
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
Οι παράµετροι τιµής, που χρησιµοποιούνται µόνο για είσοδο τιµών, περνούν απλώς την τιµή τους στις αντίστοιχες παραµέτρους της υπορουτίνας. Οποιαδήποτε µεταβολή στην τιµή τέτοιων παραµέτρων µέσα στην υπορουτίνα δεν αντανακλάται στις αντίστοιχες παραµέτρους κλήσης. Οι παράµετροι αναφοράς, είναι οι παράµετροι που περνούν στην υπορουτίνα µία σχέση απλής αναφοράς και όχι την ίδια την τιµή τους. Με τον τρόπο αυτό µια αλλαγή στην τιµή των, µέσα στην υπορουτίνα, αντανακλάται άµεσα και στις αναφερόµενες παραµέτρους της κλήσης. •
Στο παρακάτω παράδειγµα θα δούµε την χρήση των παραµέτρων τιµών. Μετά την κλήση της µεθόδου, αν και εσωτερικά αλλάζουν οι τιµές, οι αντίστοιχες παράµετροι τιµής δεν επηρεάζονται.
class Test { void meth(int i, int j) { i *= 2; j /= 2; } } class CallByValue { public static void main(String args[]) { Test ob = new Test(); int a = 15, b = 20; System.out.println("a and b before call: " + a + " " + b); ob.meth(a, b); System.out.println("a and b after call: " + a + " " + b); } }
• Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : a and b before call : 15 20 a and b after call : 15
Παναγιώτης Σφέτσος,
20
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
119
Προγραµµατισµός µε Java •
Κλάσεις - Αντικείµενα
Τα αντικείµενα χρησιµοποιούνται σαν παράµετροι αναφοράς. Αυτό σηµαίνει ότι αλλαγές µέσα στην µέθοδο αντανακλώνται και στο ίδιο το αντικείµενο.
class Test { int a, b; Test(int i, int j) { a = i; b = j; } // πέρασµα αντικειµένου void meth(Test o) { o.a *=
2;
o.b /= 2; } } class CallByRef { public static void main(String args[]) { Test ob = new Test(15, 20); System.out.println("ob.a and ob.b before call: " + ob.a + " " + ob.b); ob.meth(ob); System.out.println("ob.a and ob.b after call: " + ob.a + " " + ob.b); } }
• Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα : a and b before call : 15 20 a and b after call : 30
Παναγιώτης Σφέτσος,
10
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
120
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
Επιστροφή αντικειµένου σαν τιµή µεθόδου Μία µέθοδος επιστρέφει όλους τους τύπους δεδοµένων ακόµη και αντικείµενα. Στο παρακάτω παράδειγµα κάθε φορά που καλείται η incrByTen() δηµιουργείται ένα νέο αντικείµενο που επιστρέφεται από την µέθοδο. class Test { int a; Test(int i) { a = i; } Test incrByTen() { Test temp = new Test(a+10); return temp; } } class RetOb { public static void main(String args[]) { Test ob1 = new Test(2); Test ob2; ob2 = ob1.incrByTen(); System.out.println("ob1.a: " + ob1.a); System.out.println("ob2.a: " + ob2.a); ob2 = ob2.incrByTen(); System.out.println("ob2.a after second increase: " + ob2.a); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Ob1.a: 2 Ob2.a: 12 Ob2.a after second increase: 22
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
121
Κλάσεις - Αντικείµενα
Αναδροµή (Recursion) Όταν µία µέθοδος καλεί τον εαυτό της, τότε λέµε ότι έχουµε αναδροµή (recursion). Ένα καλό παράδειγµα για να καταλάβουµε την έννοια αυτή είναι ο υπολογισµός του Ν – παραγοντικού (Ν!). Το παραγοντικό ενός αριθµού Ν είναι το γινόµενο των αριθµών 1 x 2 x…N. Για παράδειγµα το παραγοντικό του 3 (3!) = 1 x 2 x 3 = 6. class Factorial { // συνάρτηση υπολογισµού του παραγοντικού int fact(int n) { int result; if(n==1) return 1; result = fact(n-1) * n; return result; } } class Recursion { public static void main(String args[]) { Factorial f = new Factorial(); System.out.println("Factorial of 3 is " + f.fact(3)); System.out.println("Factorial of 4 is " + f.fact(4)); System.out.println("Factorial of 5 is " + f.fact(5)); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Factorial of 3 is 6 Factorial of 4 is 24 Factorial of 5 is 120
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
122
Κλάσεις - Αντικείµενα
Τοποθετήστε µερικές println() – εντολές µέσα στην µέθοδο για να παρακολουθήσετε τα βήµατα της εκτέλεσης.
•
Στο παρακάτω παράδειγµα η αναδροµική µέθοδος printArray() εµφανίζει τα i
– πρώτα στοιχεία του πίνακα values. class RecTest { int values[]; RecTest(int i) { values = new int[i]; } // εµφάνιση του πίνακα αναδροµικά void printArray(int i) { if(i==0) return; else printArray(i-1); System.out.println("[" + (i-1) + "] " + values[i-1]); } } class Recursion2 { public static void main(String args[]) { RecTest ob = new RecTest(10); int i; for(i=0; i<10; i++) ob.values[i] = i; ob.printArray(10); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
[0] 0 [1] 1 [2] 2 [3] 3 [4] 4 [5] 5 [6] 6 [7] 7 [8] 8 [9] 9
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
123
Κλάσεις - Αντικείµενα
Ο ορισµός static Όταν ένα µέλος µιας κλάσης ορίζεται static, τότε αφ’ ενός µεν δεν χρειάζεται να αναφέρεται σε κάποιο αντικείµενο και αφ’ ετέρου προσπελάται πριν από την δηµιουργία κάποιου αντικειµένου της κλάσης του. Για αυτό η main() δηλώνεται static, για να καλείται πριν από την δηµιουργία κάποιου αντικειµένου. Μέθοδοι που δηλώνονται static έχουν τους παρακάτω περιορισµούς: 9 Μπορούν να καλούν µόνο στατικές µεθόδους 9 Μπορούν να έχουν πρόσβαση µόνο σε στατικά δεδοµένα 9 ∆εν χρησιµοποιούν το this και το super •
Στο παρακάτω παράδειγµα θα δούµε τη χρήση της δήλωσης static.
class UseStatic { static int a = 3; static int b; static void meth(int x) { System.out.println("x = " + x); System.out.println("a = " + a); System.out.println("b = " + b); } static { System.out.println("Static block initialized."); b = a * 4; } public static void main(String args[]) { meth(42); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Static block initialized. x = 42 a = 3 b = 12
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
124
Κλάσεις - Αντικείµενα
Οι πίνακες σαν αντικείµενα Οι πίνακες µπορούν να υλοποιηθούν και σαν αντικείµενα. Μία ‘στιγµιαία’ µεταβλητή του πίνακα είναι η length που επιστρέφει το µέγεθος του πίνακα. Στο παρακάτω παράδειγµα θα δούµε την χρήση της length. class Length { public static void main(String args[]) { int a1[] = new int[10]; int a2[] = {3, 5, 7, 1, 8, 99, 44, -10}; int a3[] = {4, 3, 2, 1}; System.out.println("length of a1 is " + a1.length); System.out.println("length of a2 is " + a2.length); System.out.println("length of a3 is " + a3.length); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Length of a1 is 10 Length of a2 is 8 Length of a3 is 4 •
Στο γνωστό παράδειγµα της µνήµης stack θα δούµε την χρήση της length έτσι ώστε η stack να είναι οποιουδήποτε µεγέθους.
class Stack { private int stck[]; private int tos; //αρχικοποίηση της κορυφής της stack στον δοµητή Stack(int size) { stck = new int[size]; tos = -1; } //βάλε ένα στοιχείο στην stack void push(int item) {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
125
Κλάσεις - Αντικείµενα
if(tos==stck.length-1) // χρήση του µέλους length System.out.println("Stack is full."); else stck[++tos] = item; } //βγάλε ένα στοιχείο από την stack int pop() { if(tos < 0) { System.out.println("Stack underflow."); return 0; } else return stck[tos--]; } } class TestStack2 { public static void main(String args[]) { Stack mystack1 = new Stack(5); Stack mystack2 = new Stack(8); // βάλε µερικούς αριθµούς στη stack. for(int i=0; i<5; i++) mystack1.push(i); for(int i=0; i<8; i++) mystack2.push(i); // βγάλε µερικούς αριθµούς από τη stack. System.out.println("Stack in mystack1:"); for(int i=0; i<5; i++) System.out.println(mystack1.pop()); System.out.println("Stack in mystack2:"); for(int i=0; i<8; i++) System.out.println(mystack2.pop()); } }
•
Το πρόγραµµα δηµιουργεί δύο stacks το ένα πέντε και το άλλο οκτώ στοιχείων. Η length χειρίζεται αυτόµατα τα κελιά όποιο µέγεθος και αν έχουν.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
126
Κλάσεις - Αντικείµενα
Εστιασµένες κλάσεις Κλάσεις που ορίζονται µέσα σε άλλες ονοµάζονται εστιασµένες (nested classes). Αν µία κλάση Β ορισθεί µέσα στην Α, τότε η Α έχει πρόσβαση σε όλα τα µέλη της Β ενώ το αντίστροφο δεν γίνεται. Εστιασµένες κλάσεις είναι δύο τύπων οι static και οι non-static που καλούνται και inner – classes. Οι static δεν χρησιµοποιούνται πολύ λόγω του ότι δεν έχουν πρόσβαση στα µέλη της κλάσης που τα περιβάλει. Αντίθετα χρησιµοποιούνται πολύ οι inner-classes που έχουν πρόσβαση στα µέλη της κλάσης που τα περιβάλει. Στο παρακάτω παράδειγµα θα δούµε πως ορίζουµε µία inner-class και πως τη χρησιµοποιούµε. class Outer { int outer_x = 100; void test() { Inner inner = new Inner(); inner.display(); } // Η innner - class class Inner { void display() { System.out.println("display: outer_x = " + outer_x); } }
}
class InnerClassDemo { public static void main(String args[]) { Outer outer = new Outer(); outer.test(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα :
display outer_x = 100
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
127
Κλάσεις - Αντικείµενα
Κληρονοµικότητα (Inheritance) Μία κλάση, superclass, δηµιουργείται για να µπορεί να κληρονοµηθεί από άλλες κλάσεις. Η κλάση που κληρονοµεί λέγεται subclass και είναι µια εξειδίκευση της superclass. Η κλάση αυτή εκτός από τις δικές της µεταβλητές και µεθόδους κληρονοµεί επί πλέον και όλες τις µεταβλητές και µεθόδους της superclass. Για να κληρονοµήσουµε µια κλάση τοποθετούµε την subclass µέσα στην superclass και χρησιµοποιούµε την δεσµευµένη λέξη extends. Η γενική µορφή δήλωσης µιας κλάσης που κληρονοµεί µια άλλη είναι : class extends { // σώµα της κλάσης } •
Στο παρακάτω παράδειγµα θα δούµε τον ορισµό και χρήση της superclass και subclass
//δηµιουργία superclass. class A { int i, j; void showij() { System.out.println("i and j: " + i + " " + j); }
}
// δηµιουργία µιας subclass που κληρονοµεί την A. class B extends A { int k; void showk() { System.out.println("k: " + k); } void sum() { System.out.println("i+j+k: " + (i+j+k)); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
128
Κλάσεις - Αντικείµενα
class SimpleInheritance { public static void main(String args[]) { A superOb = new A(); B subOb = new B(); // Η superclass µπορεί να χρησιµοποιεί τα δικά της. superOb.i = 10; superOb.j = 20; System.out.println("Contents of superOb: "); superOb.showij(); System.out.println(); /* Η subclass έχει πρόσβαση σε όλα τα δηµόσια µέλη της κλάσης που κληρονοµεί – την superclass. */ subOb.i = 7; subOb.j = 8; subOb.k = 9; System.out.println("Contents of subOb: "); subOb.showij(); subOb.showk(); System.out.println(); System.out.println("Sum of i, j and k in subOb:"); subOb.sum(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Contents of superOb: i and j: 10 20 Contents of subOb: i and j: 7 8 k: 9 Sum of i, j and k in subOb: i+j+k: 24 Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
129
Προγραµµατισµός µε Java
•
Κλάσεις - Αντικείµενα
Το αντικείµενο subOb έχει πρόσβαση στα i και j και στη µέθοδο showij(). Επίσης µέσα στη sum() τα i και j χρησιµοποιούνται απ’ ευθείας σαν να είναι µέλη της ίδιας της Β.
•
Η subclass δεν έχει πρόσβαση στα private µέλη της superclass.
•
Στο παρακάτω παράδειγµα θα δούµε πως θα προσθέσουµε ένα τέταρτο στοιχείο το weight στο box που έχουµε ήδη δει σε προηγούµενο κεφάλαιο. ∆ηλαδή, θα κληρονοµήσουµε τα ήδη υπάρχοντα χαρακτηριστικά και θα προσθέσουµε το βάρος.
class Box { double width; double height; double depth; // δηµιουργία κλώνου Box(Box ob) {
// πέρασµα του αντικειµένου στον constructor
width = ob.width; height = ob.height; depth = ob.depth; } // constructor µε όλες τις διαστάσεις. Box(double w, double h, double d) { width = w; height = h; depth = d; } // constructor όταν δεν ορίζουµε διαστάσεις. Box() { width = -1; height = -1; depth = -1; } // constructor όταν δηµιουργούµε κύβο. Box(double len) {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
130
Κλάσεις - Αντικείµενα
width = height = depth = len; } // υπολογισµός και επιστροφή του όγκου. double volume() { return width * height * depth; } } // Εδώ το Box θα περιλάβει το weight. class BoxWeight extends Box { double weight; // το βάρος του box // constructor για το BoxWeight. BoxWeight(double w, double h, double d, double m) { width = w; height = h; depth = d; weight = m; } } class DemoBoxWeight { public static void main(String args[]) { BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3); BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); double vol; vol = mybox1.volume(); System.out.println("Volume of mybox1 is " + vol); System.out.println("Weight of mybox1 is " + mybox1.weight); System.out.println(); vol = mybox2.volume(); System.out.println("Volume of mybox2 is " + vol); System.out.println("Weight of mybox2 is " + mybox2.weight); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
131
Κλάσεις - Αντικείµενα
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Volume of mybox1 is 3000.0 Weight of mybox1 is 34.3 Volume of mybox2 is 24.0 Weight of mybox2 is 0.076
Χρήση της λέξης super Η λέξη χρησιµοποιείται σε δύο περιπτώσεις: 9 όταν καλούµε τον δοµητή της superclass και 9 όταν θέλουµε να έχουµε πρόσβαση σε κάποιο µέλος της superclass που έχει αποκρυφτεί από την subclass. •
Στο παρακάτω παράδειγµα θα κάνουµε χρήση της super() στον προηγούµενο ορισµό του box.
class Box { private double width; private double height; private double depth; // δηµιουργία κλώνου του box. Box(Box ob) { // περασµα του αντικειµένου στο δοµητή. width = ob.width; height = ob.height; depth = ob.depth; } // δοµητής που χρησιµοποιείται µε όλες τις διαστάσεις. Box(double w, double h, double d) { width = w; height = h; depth = d; }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
132
Κλάσεις - Αντικείµενα
// δοµητής όταν δεν καθορίζονται διαστάσεις. Box() { width = -1; height = -1; depth = -1; } // δοµητής που χρησιµοποιείται µε την δηµιουργία κύβου. Box(double len) { width = height = depth = len; } // υπολογισµός και επιστροφή του όγκου. double volume() { return width * height * depth; } } // Το BoxWeight χρησιµοποιεί όλους τους δοµητές. class BoxWeight extends Box { double weight; // το βάρος του box // δόµηση κλώνου αντικειµένου. BoxWeight(BoxWeight ob) { // πέρασµα στον δοµητή. super(ob); weight = ob.weight; } // δοµητής όταν καθορίζονται όλες οι διαστάσεις. BoxWeight(double w, double h, double d, double m) { super(w, h, d); // κλήση του δοµητή της superclass weight = m; } // αρχικός δοµητής. BoxWeight() { super(); weight = -1; }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
133
Κλάσεις - Αντικείµενα
// δοµητής που χρησιµοποιείται µε την δηµιουργία του κύβου. BoxWeight(double len, double m) { super(len); weight = m; } } class DemoSuper { public static void main(String args[]) { BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3); BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); BoxWeight mybox3 = new BoxWeight();
//αρχικό
BoxWeight mycube = new BoxWeight(3, 2); BoxWeight myclone = new BoxWeight(mybox1); double vol; vol = mybox1.volume(); System.out.println("Volume of mybox1 is " + vol); System.out.println("Weight of mybox1 is " + mybox1.weight); System.out.println(); vol = mybox2.volume(); System.out.println("Volume of mybox2 is " + vol); System.out.println("Weight of mybox2 is " + mybox2.weight); System.out.println(); vol = mybox3.volume(); System.out.println("Volume of mybox3 is " + vol); System.out.println("Weight of mybox3 is " + mybox3.weight); System.out.println(); vol = myclone.volume(); System.out.println("Volume of myclone is " + vol); System.out.println("Weight of myclone is " + myclone.weight); System.out.println();
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
134
Κλάσεις - Αντικείµενα
vol = mycube.volume(); System.out.println("Volume of mycube is " + vol); System.out.println("Weight of mycube is " + mycube.weight); System.out.println(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Volume of mybox1 is 3000.0 Weight of mybox1 is 34.3 Volume of mybox2 is 24.0 Weight of mybox2 is 0.076 Volume of mybox3 is -1.0 Weight of mybox3 is -1.0 Volume of myclone is 3000.0 Weight of myclone is 34.3 Volume of mycube is 27.0 Weight of mycube is 2.0 •
Μια δεύτερη χρήση της super είναι η χρήση της σαν την λέξη this.
class A { int i; } // δηµιουργία κλάσης Β που κληρονοµεί από την A. class B extends A { int i; // this i hides the i in A B(int a, int b) { super.i = a; // i in A i = b; // i in B } void show() { System.out.println("i in superclass: " + super.i);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
135
Κλάσεις - Αντικείµενα
System.out.println("i in subclass: " + i); }
}
class UseSuper { public static void main(String args[]) { B subOb = new B(1, 2); subOb.show(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
i in superclass: 1 i in subclass: 2 •
Υπερφόρτωση µεθόδων έχουµε όταν µία µέθοδος της subclass έχει το ίδιο όνοµα µε αυτό της superclass. Στην περίπτωση αυτή η µέθοδος της subclass υπερισχύει και κρύβει την αντίστοιχη της superclass.
class A { int i, j; A(int a, int b) { i = a; j = b; } // εµφάνιση των i και j void show() { System.out.println("i and j: " + i + " " + j); }
}
class B extends A { int k; B(int a, int b, int c) { super(a, b);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
136
Κλάσεις - Αντικείµενα
k = c; } // εµφάνιση του k. Υπερφόρτωση της show() της A. void show() { System.out.println("k = " + k); } } class Override { public static void main(String args[]) { B subOb = new B(1, 2, 3); }
subOb.show(); // κλήση της show() στο B.
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω αποτέλεσµα :
k = 3 •
Αν οι µέθοδοι των superclass και subclass έχουν διαφορετικά ονόµατα τότε δεν έχουµε υπερφόρτωση. Στο παρακάτω παράδειγµα η show() της Β λαµβάνει σαν παράµετρο ένα string, ενώ η show() της Α δεν δέχεται καµία παράµετρο.
class A { int i, j; A(int a, int b) { i = a; j = b; } // εµφάνιση των i και j. void show() { System.out.println("i and j: " + i + " " + j); } } class B extends A { int k;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
137
Κλάσεις - Αντικείµενα
B(int a, int b, int c) { super(a, b); k = c; } // υπερφόρτωση της show() void show(String msg) { System.out.println(msg + k); } } class Override { public static void main(String args[]) { B subOb = new B(1, 2, 3); subOb.show("This is k: "); // καλεί την show() της B subOb.show(); // καλεί την show() στο A } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
This is k: 3 i and j: 1 2
Χρήση της κλάσης abstract Είναι η superclass – κλάση που δεν ορίζει επακριβώς την δοµή των µεθόδων της αλλά αφήνει αυτό το έργο δηλαδή, της επί µέρους συµπλήρωσης του σώµατος των µεθόδων, στις subclass – κλάσεις που την κληρονοµούν. Μία τέτοια κλάση µπορεί να περιέχει και πλήρεις µεθόδους.
Η κλάση συντάσσεται µε την
δεσµευµένη λέξη abstract και η γενική µορφή της abstract – µεθόδου είναι: abstract <τύπος> <όνοµα> (λίστα παραµέτρων); •
Στο παρακάτω παράδειγµα θα δούµε την χρήση της abstract στην κλάση και στην µέθοδο .
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
138
Κλάσεις - Αντικείµενα
abstract class A { abstract void callme(); // πλήρεις µέθοδοι επιτρέπονται επίσης !!! void callmetoo() { System.out.println("This is a concrete method."); } } class B extends A { void callme() { System.out.println("B's implementation of callme."); } } class AbstractDemo { public static void main(String args[]) { B b = new B(); b.callme(); b.callmetoo(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
B's implementation of callme. This is a concrete method. •
Στο παράδειγµα µε έντονη γραφή βλέπουµε πως συµπληρώνεται η µέθοδος callme() µέσα στην subclass – κλάση B.
•
Μπορούµε να χρησιµοποιήσουµε την δεσµευµένη λέξη final µπροστά από την µέθοδο ώστε να αποτρέψουµε την υπερφόρτωση µεθόδων.
class A { final void meth() { System.out.println("This is a final method."); } }
class B extends A {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
139
Κλάσεις - Αντικείµενα
void meth() { // ERROR! Can't override. System.out.println("Illegal!"); } }
•
Επειδή η meth() της κλάσης έχει δηλωθεί µε την final δεν µπορεί να υπερφορτωθεί από την subclass – Β. Αν µεταγλωττίσουµε το πρόγραµµα θα πάρουµε λάθος από τον µεταγλωττιστή.
Απαγόρευση κληρονοµικότητας •
Η final στον ορισµό της κλάσης απαγορεύει την κληρονοµικότητα.
final class A { // ... } // Η κλάση αυτή είναι λάθος. class B extends A { // ERROR! Can't subclass A // ... }
Η κλάση Object Είναι ειδική κλάση της java. Όλες οι κλάσεις της java είναι υποκλάσεις της Object. Έτσι η Object είναι η superclass- κλάση όλων των άλλων και εποµένως κάθε αναφορά σε µεταβλητή του τύπου Object αναφέρεται σε αντικείµενο οποιασδήποτε άλλης κλάσης. Επειδή οι πίνακες υλοποιούνται και σαν κλάσεις µία µεταβλητή του τύπου Object µπορεί να αναφέρεται και σε πίνακα.
Το string σαν αντικείµενο Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
140
Κλάσεις - Αντικείµενα
Στο παρακάτω παράδειγµα δηµιουργείται ένα αντικείµενο (µεταβλητή) της κλάσης String και εκτελείται µία µέθοδος του, η length(), που επιστρέφει το πλήθος των χαρακτήρων του string . Πριν την new το αντικείµενο δεν υπάρχει. Το πρόγραµµα απλώς εµφανίζει το αντικείµενο string. class DemoString { public static void main ( String[] args ) { String str1; //Το str1 είναι µεταβλητή που αναφέρεται στο // αντικείµενο που δεν υπάρχει ακόµη. int len; //δηµιουργία αντικειµένου της κλάσης String. str1 = new String("Hello Java"); len = str1.length(); // κλήση της µεθόδου length(). System.out.println("The string is " + len + " characters long"); } }
Ασκήσεις κλάσεων Στην παρακάτω άσκηση θα χειριστούµε τον τραπεζικό λογαριασµό ενός πελάτη. Στην επίλυση του προβλήµατος θα χρειαστούµε σαν δεδοµένα : •
Τον αριθµό λογαριασµού
•
Το όνοµα του λογαριασµού
•
Το τρέχον υπόλοιπο του λογαριασµού
Ο ∆οµητής – Constructor θα δηµιουργήσει το αντικείµενο και θα αρχικοποιήσει τα τρία αυτά στοιχεία.
Οι µέθοδοι που θα δηµιουργήσουµε θα : 9 ∆έχονται µία κατάθεση 9 Θα επεξεργάζεται ένα τσεκ 9 Θα χειρίζεται το τρέχον υπόλοιπο
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
141
Κλάσεις - Αντικείµενα
Στην παρακάτω πρώτη µορφή δεν θα περιλάβουµε τις µεθόδους. Είναι µια πρώτη κατασκευή της κλάσης. Στο κοµµάτι προγράµµατος υπάρχει και ο έλεγχος της κλάσης.
class CheckingAccount { // µεταβλητές του αντικειµένου String accountNumber; String accountHolder; int
balance;
//δοµητές CheckingAccount( String accNumber, String holder, int start ) { accountNumber = accNumber ; accountHolder = holder ; balance
= start ;
} }
// µέθοδοι
class CheckingAccountTester { public static void main( String[] args ) { CheckingAccount account1 = new CheckingAccount( "123", "Bob", 100 ); System.out.println( account1.accountNumber + " " + account1.accountHolder + " " + account1.balance ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το αποτέλεσµα : 123 Bob 100
Οι προτεινόµενοι µέθοδοι θα έχουν την παρακάτω µορφή : class CheckingAccount { // µεταβλητές του αντικειµένου
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
142
Κλάσεις - Αντικείµενα
String accountNumber; String accountHolder; int
balance;
// δοµητές - constructors CheckingAccount( String accNumber, String holder, int start ) { accountNumber = accNumber ; accountHolder = holder ; balance
= start ;
} // επιστροφή του υπολοίπου int currentBalance() {
return balance ;
} // χειρισµός της κατάθεσης void processDeposit( int amount ) { balance = balance + amount ; } // χειρισµός του check. Αφαιρείται από το υπόλοιπο το ποσό // των 15 αν είναι µικρότερο των 100000. void processCheck( int amount ) { int charge; if ( balance < 100000 ) charge = 15; else charge = 0; balance =
balance - amount - charge
;
} }
•
Ένας έλεγχος των ανωτέρω µεθόδων είναι και ο παρακάτω :
class CheckingAccountTester { public static void main( String[] args ) { CheckingAccount account1 = new CheckingAccount( "123", "Bob", 100 );
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
143
Προγραµµατισµός µε Java
Κλάσεις - Αντικείµενα
System.out.println( account1.currentBalance() ); account1.processDeposit( 2000 ); account1.processCheck( 1500 ); System.out.println( account1.currentBalance() ); } }
•
Αν εκτελέσουµε τον έλεγχο θα πάρουµε το αποτέλεσµα : 100 585
Μία ακόµη µέθοδος θα µπορούσε να είναι και η παρακάτω που εµφανίζει τα αποτελέσµατα και για τις τρεις µεθόδους. void display() { System.out.println( "\t" +
accountNumber + "\t" + accountHolder +
balance );
}
Ο έλεγχος της display() θα µπορούσε να γίνει µε τον κώδικα : class CheckingAccountTester { public static void main( String[] args ) { CheckingAccount account1 = new CheckingAccount( "123", "Bob", 100 ); account1.display() ; account1.processDeposit( 2000 ); account1.processCheck( 1500 ); account1.display() ; } }
•
Στην παρακάτω άσκηση θα υπολογίζουµε την κατανάλωση σε βενζίνη ενός αυτοκινήτου. Θα εισάγονται τα: 9 Αρχική ένδειξη χιλιοµέτρων 9 Τελική ένδειξη χιλιοµέτρων 9 Τα γαλόνια βενζίνης µεταξύ των δύο ανωτέρω µετρήσεων
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
144
Κλάσεις - Αντικείµενα
Η µέθοδος θα υπολογίζει τα γαλόνια βενζίνης που καταναλώνονται µεταξύ των δύο χιλιοµετρικών αποστάσεων. import java.io.* ; class Car { // instance variables int startMiles;
// αρχική ένδειξη χιλιοµέτρων
int endMiles;
// τελική ένδειξη χιλιοµέτρων
double gallons;
// γαλόνια µεταξύ των δύο ενδείξεων
// δοµητής Car(
int first, int last, double gals
)
{ startMiles = first ; endMiles
= last ;
gallons
= gals ;
} // µέθοδος υπολογισµού double calculateMPG() {
return (endMiles - startMiles) / gallons ;
} } class MilesPerGallon { public static void main( String[] args ) { Car car = new Car( 32456, 32810, 10.6 ); System.out.println( "Miles per gallon is " + car.calculateMPG() ); } }
•
Το κοµµάτι της εισόδου των δεδοµένων, που επιπλέον θα ελέγχει την ανωτέρω κλάση και τις µεθόδους της, θα είναι :
class MilesPerGallon { public static void main( String[] args ) throws IOException
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
145
Κλάσεις - Αντικείµενα
{ BufferedReader userIn = new BufferedReader( new InputStreamReader( System.in ) ); String line; int
startMiles, endMiles;
double gallons; System.out.println("Enter first reading:" ); line = userIn.readLine(); startMiles = Integer.parseInt( line ); System.out.println("Enter second reading:" ); line = userIn.readLine(); endMiles = Integer.parseInt( line ); System.out.println("Enter gallons:" ); line = userIn.readLine(); gallons = Integer.parseInt( line ); Car car = new Car( startMiles, endMiles, gallons
);
System.out.println( "Miles per gallon is " + car.calculateMPG() ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
146
Χειρισµός των Αρχείων
∆ιάβασµα και γράψιµο αρχείων Οι κλάσεις συνεχούς ροής FileInputStream και FileOutputStream δηµιουργούν δεσµούς ροής byte από και προς τα αρχεία. Για να ανοίξουµε ένα αρχείο δηµιουργούµε ένα αντικείµενο, από τις κλάσεις αυτές, και περνάµε σαν παράµετρο στον δοµητή το αντίστοιχο όνοµα του αρχείου. Οι δοµητές που χρησιµοποιούµε είναι: FileInputStream(string όνοµα Αρχ.) throws FileNotFoundException FileOutputStream(string όνοµα Αρχ.) throws FileNotFoundException
Όπου Όνοµα Αρχ., είναι το όνοµα του αρχείου που θέλουµε να ανοίξουµε για επεξεργασία. Αν προσπαθήσουµε να ανοίξουµε ένα αρχείο που δεν υπάρχει ή να δηµιουργήσουµε ένα αρχείο και αυτό δεν µπορεί να γίνει, δηµιουργείται η εξαίρεση FileNotFound. Αν ανοίξουµε ένα αρχείο για γράψιµο και υπάρχει ήδη αρχείο µε το ίδιο όνοµα, τότε αυτό θα διαγραφεί. 9 Όταν τελειώσουµε την επεξεργασία ενός αρχείου εκτελούµε την close(). Η γενική µορφή: void close() throws IOException. 9 ∆ιαβάζουµε από ένα αρχείο µε την read(). Η γενική µορφή: void
read()
throws
IOException. Κάθε φορά που καλείται
διαβάζεται ένα byte και επιστρέφεται σαν integer. Επιστρέφει την τιµή –1 όταν φτάσει στο τέλος του αρχείου. 9 Η try – catch χρησιµοποιείται για να αποφεύγουµε τα πιθανά λάθη στον χειρισµό των αρχείων. 9 Γράφουµε σε ένα αρχείο µε την write(). Η γενική µορφή: void write(int byteval) throws IOException.Η byteval είναι το byte που θα γράψει στο αρχείο και µάλιστα µόνο τα οκτώ χαµηλής προτεραιότητας bits θα γραφούν στο αρχείο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
147
Χειρισµός των Αρχείων
Στο παρακάτω παράδειγµα διαβάζεται ένα ήδη υπάρχον αρχείο κειµένου µε την read() και εµφανίζονται τα περιεχόµενα του στην οθόνη. Το όνοµα του αρχείου θα περάσει σαν παράµετρος κατά την εκτέλεση του προγράµµατος. Για παράδειγµα: java ShowFile myfile.txt
import java.io.*; class ShowFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; try { fin = new FileInputStream(args[0]); } catch(FileNotFoundException e) { System.out.println("File Not Found"); return; } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Usage: ShowFile File"); return; } // διάβασµα χαρακτήρων µέχρι το EOF του αρχείου. do { i = fin.read(); if(i != -1) System.out.print((char) i); } while(i != -1);
}
fin.close();
} •
Στο παρακάτω παράδειγµα αντιγράφουµε ένα αρχείο σε ένα άλλο περνώντας σαν παραµέτρους τα ονόµατα των δύο αρχείων κατά την εκτέλεση του προγράµµατος. Για παράδειγµα :
Παναγιώτης Σφέτσος,
java CopyFile FIRST.TXT SECOND.TXT
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
148
Χειρισµός των Αρχείων
import java.io.*; class CopyFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; FileOutputStream fout; try { // άνοιγµα του αρχείου εισόδου. try { fin = new FileInputStream(args[0]); } catch(FileNotFoundException e) { System.out.println("Input File Not Found"); return; } //
άνοιγµα του αρχείου εξόδου.
try { fout = new FileOutputStream(args[1]); } catch(FileNotFoundException e) { System.out.println("Error Opening Output File"); return; } } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Usage: CopyFile From To"); return; } // αντιγραφή του αρχείου. try { do { i = fin.read(); if(i != -1) fout.write(i); } while(i != -1); } catch(IOException e) { System.out.println("File Error"); }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
149
Χειρισµός των Αρχείων
fin.close(); fout.close(); } } •
Στην παρακάτω άσκηση θα γράψουµε σε ένα αρχείο µία γραµµή κειµένου την οποία στην συνέχεια θα διαβάσουµε και θα εµφανίσουµε στην οθόνη. Η παραλλαγή είναι ότι το όνοµα του αρχείου δηλώνεται µέσα στο πρόγραµµα.
import java.io.*; public class MyFirstFileWritingApp { public static void main (String args[]) {
// ορισµός της δέσµης δηµιουργίας του αρχείου FileOutputStream fout; try {
// δηµιουργία του αρχείου fout = new FileOutputStream ("myfile.txt"); // εµφανίζει µία γραµµή new PrintStream(fout).println ("hello world!"); // κλείσιµο των αρχείων. fout.close();
} // Το ‘πιάσιµο’ των πιθανόν λαθών catch (IOException e) {
System.err.println ("Unable to write to file"); System.exit(-1);
} } } •
Μία ακόµη παραλλαγή του διαβάσµατος αρχείου το όνοµα του οποίου δίνεται σαν παράµετρος κατά την εκτέλεση του προγράµµατος.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
150
Χειρισµός των Αρχείων
import java.io.*; class FileInputDemo { public static void main(String args[]) { if (args.length == 1) { try { // άνοιγµα του αρχείου που είναι η πρώτη // παράµετρος κατά την εκτέλεση του προγράµµατος. FileInputStream fstream = new FileInputStream(args[0]); // Μετατροπή της δέσµης εισόδου σε // µία δέσµη DataInputStream DataInputStream in = new DataInputStream(fstream); // διάβασµα γραµµών από το αρχείο. while (in.available() !=0) {
// εµφάνιση των γραµµών στην οθόνη. System.out.println (in.readLine());
} in.close(); } catch (Exception e) { System.err.println("File input error"); } } else System.out.println("Invalid parameters"); } } •
Η παραλλαγή της δηµιουργίας αρχείου το όνοµα του οποίου δίνεται σαν παράµετρος κατά την εκτέλεση του προγράµµατος.
import java.io.*; class FileOutputDemo { public static void main(String args[]) {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
151
Χειρισµός των Αρχείων
FileOutputStream out; //δήλωση αντικειµένου αρχείου εξόδου PrintStream p; // δήλωση αντικειµένου δέσµης εξόδου try { // δηµιουργία δέσµης εξόδου συνδεδεµένης µε το // αρχείο "myfile.txt" out = new FileOutputStream("myfile.txt"); // σύνδεση της δέσµης εµφάνισης µε την δέσµη εξόδου p = new PrintStream( out ); p.println ("This is written to a file");
}
p.close(); } catch (Exception e) { System.err.println ("Error writing to file"); }
}
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
152
Χειρισµός των Strings
Η κλάση String Τα περιεχόµενα ενός αντικειµένου string δεν µπορούν να αλλάξουν απ’ ευθείας αλλά µε δύο τρόπους : 9 δηµιουργούµε νέο αντικείµενο string µε αλλαγµένο το περιεχόµενο του 9 χρησιµοποιούµε την κλάση StringBuffer που επιτρέπει την αλλαγή των περιεχοµένων του string. •
Τα strings µπορούν να δηµιουργηθούν µε πολλούς τρόπους. Ο απλούστερος από όλους: String myString = “ Hello Java”;
•
∆ηµιουργία
σταθεράς
string
:
System.out.println(“Hello
Java”); •
Χρήση µεταβλητής string : System.out.println(myString);
Συνένωση δύο string •
Με την χρήση του τελεστή + µπορούµε να συνενώσουµε τα περιεχόµενα δύο ή περισσοτέρων string. Για παράδειγµα : String myString = “I” +“ like” + “ Java”; Το myString θα έχει σαν περιεχόµενο I like Java.
•
Ένα απλό παράδειγµα χρήσης των strings και της συνένωσης των. class StringDemo { public static void main(String args[]) { String strOb1 = "First String"; String strOb2 = "Second String"; String strOb3 = strOb1 + " and " + strOb2; System.out.println(strOb1); System.out.println(strOb2); System.out.println(strOb3); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
153
Χειρισµός των Strings
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
First String Second String First String and Second String
Μέθοδοι της string •
Η µέθοδος equals() ελέγχει αν δύο strings είναι ίδια. Boolean equals (αντικείµενο String)
•
Η µέθοδος length() επιστρέφει το µέγεθος ενός string. int length ()
•
Η µέθοδος charAt() επιστρέφει τον χαρακτήρα κάποιας θέσης µέσα στο string. char charAt(int index)
•
Στο παρακάτω παράδειγµα θα δούµε την χρήση των ανωτέρω µεθόδων.
class StringDemo2 { public static void main(String args[]) { String strOb1 = "First String"; String strOb2 = "Second String"; String strOb3 = strOb1; System.out.println("Length of strOb1: " + strOb1.length()); System.out.println("Char at index 3 in strOb1: " + strOb1.charAt(3)); if(strOb1.equals(strOb2)) System.out.println("strOb1 == strOb2"); else System.out.println("strOb1 != strOb2");
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
154
Χειρισµός των Strings
if(strOb1.equals(strOb3)) System.out.println("strOb1 == strOb3"); else System.out.println("strOb1 != strOb3"); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Length of strOb1: 12 Char at index 3 in strOb1: s strOb1 != strOb2 strOb1 == strOb3
Πίνακες µε strings Μπορούµε να έχουµε πίνακες µε στοιχεία τύπου strings. class StringDemo3 { public static void main(String args[]) { String str[] = { "one", "two", "three" }; for(int i=0; i
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Str[0]: one Str[1]: two Str[2]: three
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
155
Χειρισµός των Strings
Η τιµή null Είναι µία ειδική τιµή των strings που σηµαίνει ‘µηδέν’ αντικείµενο. Χρησιµοποιείται όταν θέλουµε να ορίσουµε ένα string που δεν δείχνει σε κάποιο αντικείµενο. Για παράδειγµα : String b = null; class nullDemo1 { public static void main(String[] args) { // δηµιουργία αντικειµένου a
String a = "Random Numbers"; // η µεταβλητή b δεν αναφέρεται σε αντικείµενο.
String b = null; // δηµιουργία του αντικειµένου c που δεν περιέχει χαρακτήρες
String c = ""; // η ( a != null ) είναι αληθής, έτσι εκτελείται η println(a).
if ( a != null ) System.out.println( a ); // η ( b != null ) είναι ψευδής,
έτσι παραλείπεται η println(b).
if ( b != null ) System.out.println( b ); // η ( c != null ) είναι αληθής,
έτσι εκτελείται η
// println(a), αλλά δεν έχει χαρακτήρες να εµφανίσει.
if ( c != null ) System.out.println( c ); } }
Οι σηµαντικότεροι δοµητές και µέθοδοι των strings // ∆οµητές - Constructors public String(); public String(String
value);
public String(StringBuffer
Παναγιώτης Σφέτσος,
buffer);
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
156
Προγραµµατισµός µε Java
Χειρισµός των Strings
// Μέθοδοι public char charAt(int
index);
public String concat(String
str);
public boolean endsWith(String public boolean equals(Object
suffix); anObject);
public boolean equalsIgnoreCase(String public int indexOf(int
anotherString);
ch);
public int indexOf(String
str);
public int length(); public boolean startsWith(String public String substring(int
prefix);
beginIndex, int endIndex);
public String toLowerCase(); public String toUpperCase(); public String trim();
Χαρακτήρες ελέγχου των αντικειµένων string Χαρακτήρες ελέγχου µπορούν να χρησιµοποιηθούν µέσα παράδειγµα ο χαρακτήρας
\n
στα strings όπως για
που αλλάζει γραµµή εµφάνισης στην οθόνη. Στο
παράδειγµα θα δούµε την χρήση του χαρακτήρα \n. class beautyShock { public static void main(String[] args) { String line1 = "Only to the wanderer comes\n"; String line2 = "Ever new this shock of beauty\n"; String poem }
= line1 + line2;
System.out.print( poem );
}
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε τα παρακάτω αποτελέσµατα :
Only to the wanderer comes Ever new this shock of beauty
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
157
Προγραµµατισµός µε Java
Χειρισµός των Strings
Ασκήσεις επί των string •
∆ηµιουργία ενός string από άλλο.
class MakeString { public static void main(String args[]) { char c[] = {'J', 'a', 'v', 'a'}; String s1 = new String(c); String s2 = new String(s1); System.out.println(s1); System.out.println(s2); } } •
∆ηµιουργία ενός string από ένα υποσύνολο χαρακτήρων αποθηκευµένων σε πίνακα.
class SubStringCons { public static void main(String args[]) { byte ascii[] = {65, 66, 67, 68, 69, 70 }; String s1 = new String(ascii); System.out.println(s1); String s2 = new String(ascii, 2, 3); System.out.println(s2); } } •
Χρήση της συνένωσης για την αποφυγή δηµιουργίας µεγάλων γραµµών κειµένου.
class ConCat { public static void main(String args[]) { String longStr = "This could have been " + "a very long line that would have " + "wrapped around.
But string concatenation " +
"prevents this."; System.out.println(longStr); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
158
Προγραµµατισµός µε Java •
Χειρισµός των Strings
Χρήση της getChars().
class getCharsDemo { public static void main(String args[]) { String s = "This is a demo of the getChars method."; int start = 10; int end = 14; char buf[] = new char[end - start]; s.getChars(start, end, buf, 0); System.out.println(buf); } }
•
Σύγκριση µε τις equals() και equalsIgnoreCase().
class equalsDemo { public static void main(String args[]) { String s1 = "Hello"; String s2 = "Hello"; String s3 = "Good-bye"; String s4 = "HELLO"; System.out.println(s1 + " equals " + s2 + " -> " + s1.equals(s2)); System.out.println(s1 + " equals " + s3 + " -> " + s1.equals(s3)); System.out.println(s1 + " equals " + s4 + " -> " + s1.equals(s4)); System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " + s1.equalsIgnoreCase(s4)); } } •
Ταξινόµηση φυσαλίδας –bubble για strings.
class SortString { static String arr[] = { "Now", "is", "the", "time", "for", "all", "good", "men",
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
159
Προγραµµατισµός µε Java
Χειρισµός των Strings
"to", "come", "to", "the", "aid", "of", "their", "country"}; public static void main(String args[]) { for(int j = 0; j < arr.length; j++) { for(int i = j + 1; i < arr.length; i++) { if(arr[i].compareTo(arr[j]) < 0) { String t = arr[j]; arr[j] = arr[i]; arr[i] = t; } } System.out.println(arr[j]); } } } •
Χρήση της indexOf() και lastIndexOf().
class indexOfDemo { public static void main(String args[]) { String s = "Now is the time for all good men " + "to come to the aid of their country."; System.out.println(s); System.out.println("indexOf(t) = " + s.indexOf('t')); System.out.println("lastIndexOf(t) = " + s.lastIndexOf('t')); System.out.println("indexOf(the) = " + s.indexOf("the")); System.out.println("lastIndexOf(the) = " + s.lastIndexOf("the")); System.out.println("indexOf(t, 10) = " + s.indexOf('t', 10)); System.out.println("lastIndexOf(t, 60) = " + s.lastIndexOf('t', 60)); System.out.println("indexOf(the, 10) = " + s.indexOf("the", 10));
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
160
Προγραµµατισµός µε Java
Χειρισµός των Strings
System.out.println("lastIndexOf(the, 60) = " + s.lastIndexOf("the", 60)); } }
•
Αντικατάσταση Substring.
class StringReplace { public static void main(String args[]) { String org = "This is a test. This is, too."; String search = "is"; String sub = "was"; String result = ""; int i; do { // αντικατάσταση όλων των substrings που ταιριάζουν System.out.println(org); i = org.indexOf(search); if(i != -1) { result = org.substring(0, i); result = result + sub; result = result + org.substring(i + search.length()); org = result; } } while(i != -1); } }
•
Χρήση της trim() για σωστή εκτέλεση των εντολών.
import java.io.*; class UseTrim { public static void main(String args[]) throws IOException {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
161
Χειρισµός των Strings
//δηµιουργία ενός BufferedReader χρησιµοποιώντας την System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter 'stop' to quit."); System.out.println("Enter State: "); do { str = br.readLine(); str = str.trim(); // remove whitespace if(str.equals("Illinois")) System.out.println("Capital is Springfield."); else if(str.equals("Missouri")) System.out.println("Capital is Jefferson City."); else if(str.equals("California")) System.out.println("Capital is Sacramento."); else if(str.equals("Washington")) System.out.println("Capital is Olympia."); // ... } while(!str.equals("stop")); } }
•
Χρήση των toUpperCase() και toLowerCase().
class ChangeCase { public static void main(String args[]) { String s = "This is a test."; System.out.println("Original: " + s); String upper = s.toUpperCase(); String lower = s.toLowerCase(); System.out.println("Uppercase: " + upper); System.out.println("Lowercase: " + lower); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
162
Χειρισµός των Strings
Το length και η capacity του StringBuffer.
class StringBufferDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer("Hello"); System.out.println("buffer = " + sb); System.out.println("length = " + sb.length()); System.out.println("capacity = " + sb.capacity()); } }
•
Χρήση των charAt() και setCharAt().
class setCharAtDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer("Hello"); System.out.println("buffer before = " + sb); System.out.println("charAt(1) before = " + sb.charAt(1)); sb.setCharAt(1, 'i'); sb.setLength(2); System.out.println("buffer after = " + sb); System.out.println("charAt(1) after = " + sb.charAt(1)); } }
•
Χρήση της append().
class appendDemo { public static void main(String args[]) { String s; int a = 42; StringBuffer sb = new StringBuffer(40); s = sb.append("a = ").append(a).append("!").toString(); System.out.println(s); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
163
Χειρισµός των Strings
Χρήση της insert().
class insertDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer("I Java!"); sb.insert(2, "like "); System.out.println(sb); } }
•
Χρήση της reverse()για αντιστροφή string σε StringBuffer.
class ReverseDemo { public static void main(String args[]) { StringBuffer s = new StringBuffer("abcdef"); System.out.println(s); s.reverse(); System.out.println(s); } }
•
Χρήση της delete() και deleteCharAt().
class deleteDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer("This is a test."); sb.delete(4, 7); System.out.println("After delete: " + sb); sb.deleteCharAt(0); System.out.println("After deleteCharAt: " + sb); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
164
Προγραµµατισµός µε Java •
Χειρισµός των Strings
Χρήση της replace().
class replaceDemo { public static void main(String args[]) { StringBuffer sb = new StringBuffer("This is a test."); sb.replace(5, 7, "was"); System.out.println("After replace: " + sb); } }
Πέρασµα παραµέτρων κατά την εκτέλεση του προγράµµατος Κατά την εκτέλεση του προγράµµατος µπορούµε να περάσουµε παραµέτρους στην main() που αποθηκεύονται στον πίνακα της String. Οι παράµετροι συντάσσονται, µε σειρά, µετά το όνοµα του προγράµµατος όταν εκτελείται στην γραµµή εντολών. Ήδη έχουµε χρησιµοποιήσει το πέρασµα παραµέτρων κατά την εκτέλεση του προγράµµατος και στην επεξεργασία των αρχείων αλλά και σε άλλες ασκήσεις. •
Στο παρακάτω παράδειγµα θα εµφανίσουµε τις παραµέτρους που περνάµε κατά την εκτέλεση του προγράµµατος στην γραµµή εντολών.
class CommandLine { public static void main(String args[]) { for(int i=0; i
•
Αν εκτελέσουµε το πρόγραµµα µε τις παρακάτω παραµέτρους :
java CommandLine I like Java Numbers 1 2 •
Θα πάρουµε τα αποτελέσµατα :
Args[0]: Args[1]: Args[2]: Args[3]: Args[4]: Args[5]:
I like Java Numbers 1 2
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
165
Applets
Βασικές αρχές Τα applets είναι µικρά προγράµµατα που µεταφέρονται, αυτόµατα εγκαθίστανται και εκτελούνται µέσα στο Internet. Η εκτέλεση των applets γίνεται µέσα από πλοηγούς του Internet (browsers). Τα προγράµµατα αυτά έχουν διαφορετική σύνταξη από τα προγράµµατα που έχουµε δει µέχρι τώρα και δεν περιέχουν την µέθοδο main(). Θα γράψουµε ένα µικρό applet, που εµφανίζει ένα µήνυµα, και θα εξηγήσουµε βήµα προς βήµα τις εντολές που χρησιµοποιούµε σε αυτό. import java.awt.*; import java.applet.*; public class SimpleApplet extends Applet { public void paint(Graphics g) { g.drawString("A Simple Applet", 20, 20); } }
Όπου: •
Η εντολή import java.awt.*, εισάγει τις κλάσεις της βιβλιοθήκης Abstract Window Toolkit (AWT). Η επικοινωνία µε τα applets γίνεται µέσα από την AWT και όχι από τις κλάσεις κονσόλας - I/O. Η AWT παρέχει γραφικό παραθυρικό περιβάλλον.
•
Η εντολή import java. applet.*, εισάγει το applet – package που περιέχει την κλάση Applet. Κάθε applet που δηµιουργούµε είναι subclass της κλάσης Applet.
•
Η εντολή public class SimpleApplet extends Applet, δηλώνει την κλάση SimpleApplet σαν public, επειδή θα προσπελαθεί από κώδικα που είναι έξω από το πρόγραµµα.
•
Η εντολή paint() έχει µία παράµετρο τύπου Graphics που περιγράφει το περιβάλλον στο οποίο τρέχει το applet.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
166
Applets
Μέσα στην paint() καλείται η drawString() που είναι µέλος της κλάσης Graphics και εµφανίζει ένα string σε συγκεκριµένες συντεταγµένες Χ και Υ. Οι συντεταγµένες Χ και Υ αρχίζουν από το άνω αριστερό άκρο του παραθύρου στην θέση 0, 0.
•
Η γενική µορφή της drawString() είναι η :
void drawString(µήνυµα-string, int x, int y); •
Μεταγλωττίζουµε το πρόγραµµα κανονικά όπως και τις λοιπές εφαρµογές αλλά το εκτελούµε µε δύο διαφορετικούς τρόπους:
1) Γράφουµε ένα µικρό ΗΤΜL – αρχείο που θα τρέξει το applet µέσα στον πλοηγό του Web. H µέθοδος απαιτεί αρκετό χρόνο για την εκτέλεση του applet. Ένας ΗΤΜL – κώδικας που θα τρέξει το Simpleapplet είναι ο παρακάτω:
Πρώτα εκτελούµε τον πλοηγό, είτε τον Microsoft Exlorer, είτε τον Netscape Navigator και έπειτα φορτώνουµε τον κώδικα HTML που θα τρέξει το applet. 2) Χρησιµοποιούµε ένα applet viewer δηλαδή, ένα εργαλείο που εκτελεί τα applets όπως αυτόν της JDK, τον appletviewer. O τρόπος αυτός είναι γρηγορότερος στην εκτέλεση των applets. Για να τρέξουµε το applet µέσα από ένα viewer πρέπει επίσης να τρέξουµε το HTML – αρχείο. Για παράδειγµα αν το HTML – αρχείο έχει όνοµα RunApp.html, τότε η κλήση του viewer θα µπορούσε να είναι : C:\>appletviewer RunApp.html Για να αυξήσουµε ακόµη περισσότερο την ταχύτητα εκτέλεσης του applet γράφουµε τον κώδικα HTML – σαν σχόλιο µέσα στο applet και µετά το εκτελούµε µε τον appletviewer. ∆ηλαδή, το προηγούµενο applet εµφάνισης του µηνύµατος θα µπορούσε να γραφεί :
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
167
Applets
import java.awt.*; import java.applet.*; /* */ public class SimpleApplet extends Applet { public void paint(Graphics g) { g.drawString("A Simple Applet", 20, 20); } }
•
setBackground( Color.pink ), µία άλλη µέθοδος της Graphics για εφαρµογή χρώµατος στο background.
Μέθοδοι Ζωγραφικής Σχεδιασµός κύκλου Η µέθοδος drawOval() σχεδιάζει κύκλο. Η γενική µορφή της είναι : •
drawOval( int X, int Y, int width, int height )
Στο παρακάτω παράδειγµα θα δούµε την χρήση της drawOval(). import java.applet.Applet; import java.awt.*; // assume that the drawing area is 150 by 150 public class JustOneCircle extends Applet {
final int radius = 25; public void paint ( Graphics gr ) { setBackground( Color.lightGray ); gr.drawOval( (150/2 - radius), (150/2 - radius), radius*2,
radius*2 ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
168
Προγραµµατισµός µε Java
Applets
Σχεδιασµός τετραγώνου Η µέθοδος drawRect() σχεδιάζει τετράγωνο. Η γενική µορφή της είναι : drawRect(int
x, int
y, int
width, int
height)
Στο παρακάτω παράδειγµα θα δούµε την χρήση της drawRect(). import java.applet.Applet; import java.awt.*; // υποθέτουµε ότι η επιφάνεια σχεδιασµού είναι 150 επι 150 public class SquareAndRectangle extends Applet {
final int areaSide = 150 ; final int width = 100, height = 50; public void paint ( Graphics gr ) { setBackground( Color.green ); setColor( Color.blue ); // εξωτερικό περίγραµµα της επιφάνειας gr.drawRect( 0, 0, areaSide-1, areaSide-1 ); // σχεδιασµός του εσωτερικού τετραγώνου. gr.drawRect( areaSide/2 - width/2 , areaSide/2 - height/2, width, height ); }
}
•
Σχεδιασµός γραµµής. H γενική µορφή της µεθόδου είναι : drawLine(int
Παναγιώτης Σφέτσος,
x1, int
y1, int
Ιωάννης Σταµέλος,
x2, int
y2)
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
169
Applets
Ένα ολοκληρωµένο πρόγραµµα γραφικών που σχεδιάζει πλαίσιο επάνω στο
•
οποίο στη συνέχεια ζωγραφίζουµε κάποιο σχήµα. import java.awt.*; import java.applet.Applet; public class ShapesDemo extends Applet { final static int maxCharHeight = 15; public void init() { validate(); } public void paint(Graphics g) { Dimension d = size(); int x = 5; int y = 7; Color bg = getBackground(); Color fg = getForeground(); int gridWidth = d.width / 7; int gridHeight = d.height / 2; int stringY = gridHeight - 7; int rectWidth = gridWidth - 2*x; int rectHeight = stringY - maxCharHeight - y; g.setColor(bg); g.draw3DRect(0, 0, d.width - 1, d.height - 1, true); g.draw3DRect(3, 3, d.width - 7, d.height - 7, false); g.setColor(fg); // drawLine() g.drawLine(x, y+rectHeight-1, x + rectWidth, y); // x1, y1, x2, y2 g.drawString("drawLine()", x, stringY); x += gridWidth;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
170
Applets
// drawRect() g.drawRect(x, y, rectWidth, rectHeight); // x, y, width, height g.drawString("drawRect()", x, stringY); x += gridWidth; // draw3DRect() g.setColor(bg); g.draw3DRect(x, y, rectWidth, rectHeight, true); g.setColor(fg); g.drawString("draw3DRect()", x, stringY); x += gridWidth; // drawRoundRect() g.drawRoundRect(x, y, rectWidth, rectHeight, 10, 10); // x, y, w, h, arcw, arch g.drawString("drawRoundRect()", x, stringY); x += gridWidth; // drawOval() g.drawOval(x, y, rectWidth, rectHeight); // x, y, w, h g.drawString("drawOval()", x, stringY); x += gridWidth; // drawArc() g.drawArc(x, y, rectWidth, rectHeight, 90, 135); // x, y, w, h g.drawString("drawArc()", x, stringY); x += gridWidth; // drawPolygon() Polygon polygon = new Polygon(); polygon.addPoint(x, y); polygon.addPoint(x+rectWidth, y+rectHeight); polygon.addPoint(x, y+rectHeight); polygon.addPoint(x+rectWidth, y);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
171
Applets
//polygon.addPoint(x, y); //don't complete; fill will, draw won't g.drawPolygon(polygon); g.drawString("drawPolygon()", x, stringY); x = 5 + gridWidth; y += gridHeight; stringY += gridHeight; // fillRect() g.fillRect(x, y, rectWidth, rectHeight); // x, y, width, height g.drawString("fillRect()", x, stringY); x += gridWidth; // fill3DRect() g.setColor(bg); g.fill3DRect(x, y, rectWidth, rectHeight, true); g.setColor(fg); g.drawString("fill3DRect()", x, stringY); x += gridWidth; // fillRoundRect() g.fillRoundRect(x, y, rectWidth, rectHeight, 10, 10); // x, y, w, h, arcw, arch g.drawString("fillRoundRect()", x, stringY); x += gridWidth; // fillOval() g.fillOval(x, y, rectWidth, rectHeight); // x, y, w, h g.drawString("fillOval()", x, stringY); x += gridWidth; // fillArc() g.fillArc(x, y, rectWidth, rectHeight, 90, 135); // x, y, w, h g.drawString("fillArc()", x, stringY);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
172
Applets
x += gridWidth; // fillPolygon() Polygon filledPolygon = new Polygon(); filledPolygon.addPoint(x, y); filledPolygon.addPoint(x+rectWidth, y+rectHeight); filledPolygon.addPoint(x, y+rectHeight); filledPolygon.addPoint(x+rectWidth, y); //filledPolygon.addPoint(x, y); g.fillPolygon(filledPolygon); g.drawString("fillPolygon()", x, stringY); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
173
Graphics – Windows - GUI
Abstract Window Toolkit (AWT) Την βιβλιοθήκη αυτή χρησιµοποιήσαµε στα Applets. Θα την χρησιµοποιήσουµε όµως και τώρα, επειδή περιέχει κλάσεις και µεθόδους
που
χρησιµοποιούνται στα
παράθυρα – windows.
Ιεραρχία των παραθύρων Η AWT ορίζει τα παράθυρα κατά ιεραρχικό τρόπο.
• H κλάση – Component (Συστατικό) Είναι η πρώτη στην ιεραρχία abstract – κλάση. Ορίζει εκατοντάδες µεθόδους που χειρίζονται τα συµβάντα (events) όπως για παράδειγµα το πάτηµα των πλήκτρων του ποντικιού, η τον χειρισµό των παραθύρων. Τέτοιοι χειρισµοί παραθύρων είναι η ελαχιστοποίηση και επαναφορά των, η αυξοµείωση του µεγέθους των και επαναφορά των χρωµάτων των. Τα αντικείµενα της κλάσης λέγονται Συστατικά (components). •
Container Είναι υποκλάση - subclass της component και περιέχει µεθόδους που επιτρέπουν το φώλιασµα άλλων Συστατικών. Οι µέθοδοι αυτοί χειρίζονται την τοποθέτηση των Συστατικών και συντελούν στην ανάπτυξη εφαρµογών µε όµορφο οπτικά περιβάλλον.
•
Panel Μαζί µε την Window είναι οι δύο υποκλάσεις της Container. Η panel είναι η superclass των applets. Τα applets τρέχουν επάνω στα panels. Προσθέτουµε άλλα Συστατικά επάνω στο panel µε την µέθοδο add() που κληρονοµεί από την container. Μετά την τοποθέτηση των Συστατικών µπορούµε να τα χειριστούµε µε τις µεθόδους setLocation(), setSize() και setBounds().
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
174
Graphics – Windows - GUI
Window Η µέθοδος αυτή δηµιουργεί ένα παράθυρο αρχικού επιπέδου (top level). Αρχικού επιπέδου παράθυρο σηµαίνει ότι δεν περιέχεται µέσα σε άλλα αντικείµενα αλλά ‘τρέχει’ επάνω στο γραφικό περιβάλλον του λειτουργικού.
•
Frame Είναι υποκλάση της Window και περιέχει την µπάρα τίτλου, την µπάρα του µενού επιλογών, τα πλαίσια και τις γωνίες χειρισµού του µεγέθους του παραθύρου. Αν δηµιουργήσουµε ένα αντικείµενο – frame µέσα από ένα applet, τότε θα δούµε το προειδοποιητικό µήνυµα : “Warning: Applet Window” που µας προειδοποιεί ότι ένα frame δηµιουργήθηκε.
•
Canvas Παρόλο που δεν είναι ιεραρχικό µέλος των applets ή των παραθύρων είναι ένα άλλο σηµαντικό είδος λευκού - παραθύρου που το χρησιµοποιούµε για να σχεδιάζουµε γραφικά σχήµατα.
H εργασία µε τα Frame Windows Τις περισσότερες φορές τα παράθυρα που θα χρησιµοποιούµε θα είναι του τύπου frame. Συνήθως δηµιουργούµε τέτοια παράθυρα µέσα στα applets ή αρχικά παράθυρα µεγάλων εφαρµογών. Υποστηρίζει
τους δοµητές: Frame() και Frame(τίτλος -
string). Ο πρώτος δηµιουργεί ένα παράθυρο χωρίς τίτλο ενώ ο δεύτερος µε τίτλο που ορίζεται από το string. Οι διαστάσεις του παραθύρου ορίζονται µετά την δηµιουργία του. •
Ορισµός των διαστάσεων του παραθύρου Η µέθοδος - setSize() καθορίζει το µέγεθος του παραθύρου. Η γενική της µορφή είναι: void setSize(int new width, int new height) void setSize(Dimension newSize)
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
175
Graphics – Windows - GUI
Όπου: new width και new height, καθορίζουν το νέο µέγεθος του παραθύρου. Dimension, είναι το αντικείµενο µε τα πεδία width και height που δίνουν τιµή στο newSize. Οι διαστάσεις ορίζονται σε pixels. Η µέθοδος getSize() επιστρέφει τις τρέχουσες διαστάσεις του παραθύρου. Η γενική της µορφή: Dimension getSize() •
Εµφάνιση και απόκρυψη παραθύρου Ένα παράθυρο όταν δηµιουργείται δεν εµφανίζεται απ’ ευθείας αλλά µε την χρήση της setVisible(). Η γενική της µορφή είναι : void setVisible(boolean visibleFlag) Αν η visibleFlag είναι true, τότε το παράθυρο φαίνεται, διαφορετικά είναι κρυµένο.
•
Ορισµός του τίτλου παραθύρου Ορίζουµε ή αλλάζουµε τον τίτλο του παραθύρου µε την setTitle(). Η γενική της µορφή είναι : void setTitle(String newTitle) Η newTitle, είναι ο τίτλος του παραθύρου.
•
Κλείσιµο παραθύρου Όταν τελειώνουµε τις εργασίες µε ένα παράθυρο το διαγράφουµε από την οθόνη µε την setVisible(false). Για να κλείσουµε ένα παράθυρο χρησιµοποιούµε επίσης την µέθοδο windowClosing().
•
Στο παρακάτω παράδειγµα θα δηµιουργήσουµε ένα frame – παράθυρο µε τον πλέον εύκολο τρόπο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
176
Προγραµµατισµός µε Java
Graphics – Windows - GUI
import java.awt.*; public class GUI1 { public static void main(String[] args) { Frame frm = new Frame(); frm.setSize( 150, 100 ); frm.setVisible( true ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο το οποίο όµως δεν µπορούµε να κλείσουµε µε το x στο δεξί άνω άκρο του παραθύρου διότι
δεν
έχει
ενεργοποιηθεί
η
µέθοδος
windowClosing()
της
WindowListener. Κλείνουµε το παράθυρο στο περιβάλλον DOS µε τα πλήκτρα Ctrl και c.
•
Οι διαστάσεις του παραθύρου µπορεί να αλλάξουν και κατά την εκτέλεση του προγράµµατος.
import java.awt.*; public class GUI2 { public static void main(String[] args) { Frame frm = new Frame(); int width = 20; int height = 10; frm.setVisible( true ); for ( int count=1; count<300; count++ ) frm.setSize( width++, height++ ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
177
Graphics – Windows - GUI
Φτιάχνουµε την δική µας κλάση για να την χρησιµοποιούµε όποτε θέλουµε να εµφανίσουµε ένα παράθυρο µε κάποιο µήνυµα.
import java.awt.*; class myFrame extends Frame { public void paint(Graphics g) { 50.
//εµφανίζουµε ένα µήνυµα στο frame, στις θέσεις 10 και g.drawString("A myFrame object", 10, 50 );
} } public class GUI3 { public static void main(String[] args) { //δηµιουργία αντικειµένου παραθύρου τύπου frame. myFrame frm = new myFrame(); // πλάτος = 150 και ύψος = 100 pixels. frm.setSize( 150, 100 ); //εµφάνιση στην οθόνη. frm.setVisible( true ); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
•
Η
µέθοδος
drawString()
εµφανίζει
µηνύµατα
στο
παράθυρο.
Η
System.out.println(), που χρησιµοποιούσαµε µέχρι τώρα για την εµφάνιση µηνυµάτων στο DOS, δεν ισχύει στο παραθυρικό περιβάλλον.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
178
Graphics – Windows - GUI
∆ηµιουργία GUI – περιβάλλοντος (Graphical User Interface (GUI)) Τα τρία µέρη εφαρµογής γραφικών είναι : 9 Τα Συστατικά (αντικείµενα) που αποτελούν το γραφικό περιβάλλον. 9 Listeners που λαµβάνουν τα συµβάντα και ανταποκρίνονται σε αυτά. 9 Ο κώδικας της εφαρµογής. Μέχρι τώρα είδαµε το πρώτο µέρος. Παρακάτω θα εξετάσουµε τα άλλα δύο µέρη.
Event Listeners Στην εµβάθυνση του προγραµµατισµού για την δηµιουργία και χρήση γραφικού περιβάλλοντος,
θα εξετάσουµε την χρήση του event listener που επιτρέπει την
ανταπόκριση σε κάποια συµβάντα όπως για παράδειγµα το κλείσιµο του παραθύρου µε το ποντίκι. Το event listener είναι ένα αντικείµενο που ‘ακούει’ τα συµβάντα που προέρχονται από κάποιο άλλο GUI - αντικείµενο. Όταν δηµιουργηθεί συµβάν, η java δηµιουργεί ένα αντικείµενο που στέλνεται στην κατάλληλη µέθοδο του listener η οποία ανταποκρίνεται στο συµβάν αυτό. Για να επιτευχθεί αυτό πρέπει το πρόγραµµα να κάνουµε τα παρακάτω δύο πράγµατα: 9 Να δηµιουργήσουµε ένα αντικείµενο event listener για τον τύπο του συµβάντος 9 Το αντικείµενο αυτό πρέπει να δηλωθεί µέσα στο GUI - αντικείµενο που δηµιουργεί το συµβάν.
Η κλάση -WindowAdapter Η κλάση αυτή δηµιουργεί αντικείµενα που είναι listeners για τα συµβάντα των παραθύρων. Στον παρακάτω κώδικα θα δηµιουργήσουµε µία κλάση κλεισίµατος του παραθύρου µε το κλικ του ποντικιού. public class WindowQuitter extends WindowAdapter { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
179
Graphics – Windows - GUI
Έτσι το πρόγραµµα µε την χρήση της κλάσης τερµατισµού του παραθύρου διαµορφώνεται σε:
import java.awt.*; import java.awt.event.*; class myFrame extends Frame {
public void paint(Graphics g) { g.drawString("Click the close button", 10, 50 ); }
} class WindowQuitter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit( 0 ); //έξοδος από το πρόγραµµα } } public class GUItester { public static void main(String[] args) { // δηµιουργία ενός αντικειµένου – myFrame. myFrame frm = new myFrame(); // δηµιουργία listener για το frame. WindowQuitter wquit = new WindowQuitter(); // δήλωση του listener µέσα στο frame. frm.addWindowListener( wquit ); frm.setSize( 150, 100 ); frm.setVisible( true ); } }
•
Μέσα στο συστατικό- frame χρησιµοποιούµε την addWindowListener() για να δηλώσουµε τον listener.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
180
Graphics – Windows - GUI
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο το οποίο πλέον κλείνει µε το κλικ του ποντικιού .
•
Στην παρακάτω παραλλαγή του προηγουµένου προγράµµατος θα ορίσουµε την main() µέσα στην κλάση myFrame έτσι ώστε ο κώδικας να γίνει λιγότερος. Το αποτέλεσµα βέβαια είναι ακριβώς το ίδιο.
import java.awt.*; import java.awt.event.*; public class myFrame extends Frame { public void paint(Graphics g) { g.drawString("Click the close button", 10, 50 ); } public static void main(String[] args) { myFrame frm = new myFrame(); WindowQuitter wquit = new WindowQuitter(); frm.addWindowListener( wquit ); frm.setSize( 150, 100 ); frm.setVisible( true ); } } class WindowQuitter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit( 0 ); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
181
Graphics – Windows - GUI
Μία παραλλαγή δηµιουργίας παραθύρου µέσα από applet είναι και η παρακάτω.
import java.awt.*; import java.awt.event.*; import java.applet.*; /*
*/ // δηµιουργία υποκλάσης Frame. class SampleFrame extends Frame { SampleFrame(String title) { super(title); // δηµιουργία αντικειµένου για χειρισµό παραθυρικών συµβάντων
MyWindowAdapter adapter = new MyWindowAdapter(this); // δήλωση του αντικειµένου για να λαµβάνει τα συµβάντα addWindowListener(adapter); } public void paint(Graphics g) { g.drawString("This is in frame window", 10, 40); } } class MyWindowAdapter extends WindowAdapter { SampleFrame sampleFrame; public MyWindowAdapter(SampleFrame sampleFrame) { this.sampleFrame = sampleFrame; } public void windowClosing(WindowEvent we) { sampleFrame.setVisible(false); }
} // δηµιουργία παραθύρου frame.
public class AppletFrame extends Applet { Frame f; public void init() {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
182
Graphics – Windows - GUI
f = new SampleFrame("A Frame Window"); f.setSize(250, 250); f.setVisible(true); } public void start() { f.setVisible(true); } public void stop() { f.setVisible(false); } public void paint(Graphics g) { g.drawString("This is in applet window", 10, 20); } }
•
Στο παρακάτω παράδειγµα γίνεται χειρισµός
του ποντικιού µέσα σε
παράθυρο – Frame. ∆ηµιουργία νέου παραθύρου µε το κλικ του ποντικιού.
import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ // δηµιουργία υποκλάσης του Frame. class SampleFrame extends Frame implements MouseListener, MouseMotionListener { String msg = ""; int mouseX=10, mouseY=40; int movX=0, movY=0; SampleFrame(String title) { super(title);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
183
Graphics – Windows - GUI
// δήλωση του αντικειµένου που θα λαµβάνει τα δικά του συµβάντα
addMouseListener(this); addMouseMotionListener(this); // δηµιουργία αντικειµένου για χειρισµό των συµβάντων παραθύρων
MyWindowAdapter adapter = new MyWindowAdapter(this); // δήλωση του αντικειµένου για να λαµβάνει τα συµβάντα addWindowListener(adapter); } // χειριςµός των κλικ του ποντικιού. public void mouseClicked(MouseEvent me) { } // χειρισµός της εισόδου ποντικιού (child – window).
public void mouseEntered(MouseEvent evtObj) { // save coordinates mouseX = 10; mouseY = 54; msg = "Mouse just entered child."; repaint(); } // χειρισµός της εξόδου ποντικιού (child – window). public void mouseExited(MouseEvent evtObj) { // save coordinates mouseX = 10; mouseY = 54; msg = "Mouse just left child window."; repaint(); } // χειρισµός των κλικ του ποντικιού. public void mousePressed(MouseEvent me) { // save coordinates mouseX = me.getX(); mouseY = me.getY();
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
184
Graphics – Windows - GUI
msg = "Down"; repaint(); } // Handle mouse released. public void mouseReleased(MouseEvent me) { // save coordinates mouseX = me.getX(); mouseY = me.getY(); msg = "Up"; repaint(); } // Handle mouse dragged. public void mouseDragged(MouseEvent me) { // save coordinates mouseX = me.getX(); mouseY = me.getY(); movX = me.getX(); movY = me.getY(); msg = "*"; repaint(); } // Handle mouse moved. public void mouseMoved(MouseEvent me) { // save coordinates movX = me.getX(); movY = me.getY(); repaint(0, 0, 100, 60); } public void paint(Graphics g) { g.drawString(msg, mouseX, mouseY); g.drawString("Mouse at " + movX + ", " + movY, 10, 40); } } class MyWindowAdapter extends WindowAdapter { SampleFrame sampleFrame;
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
185
Graphics – Windows - GUI
public MyWindowAdapter(SampleFrame sampleFrame) { this.sampleFrame = sampleFrame; } public void windowClosing(WindowEvent we) { sampleFrame.setVisible(false); } } // παράθυρο applet. public class WindowEvents extends Applet implements MouseListener, MouseMotionListener { SampleFrame f; String msg = ""; int mouseX=0, mouseY=10; int movX=0, movY=0; // δηµιουργία παραθύρου - frame. public void init() { f = new SampleFrame("Handle Mouse Events"); f.setSize(300, 200); f.setVisible(true); // δήλωση του αντικειµένου για να λαµβάνει τα συµβάντα ποντικιού
addMouseListener(this); addMouseMotionListener(this); } // τερµατισµός του παραθύρου-frame όταν σταµατά το applet. public void stop() { f.setVisible(false); } //εµφάνιση του παραθύρου-frame όταν ξεκινά το applet. public void start() { f.setVisible(true); } // χειρισµός των κλικ του ποντικιού. public void mouseClicked(MouseEvent me) { }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
186
Graphics – Windows - GUI
// χειρισµός εισόδου του ποντικιού. public void mouseEntered(MouseEvent me) { // save coordinates mouseX = 0; mouseY = 24; msg = "Mouse just entered applet window."; repaint(); } // χειρισµός εξόδου του ποντικιού. public void mouseExited(MouseEvent me) { // save coordinates mouseX = 0; mouseY = 24; msg = "Mouse just left applet window."; repaint(); } // χειρισµός των κλικ ποντικιού. public void mousePressed(MouseEvent me) { // save coordinates mouseX = me.getX(); mouseY = me.getY(); msg = "Down"; repaint(); } // χειρισµός της διακοπής πατήµατος των πλήκτρων του ποντικιού. public void mouseReleased(MouseEvent me) { // save coordinates mouseX = me.getX(); mouseY = me.getY(); msg = "Up"; repaint(); } // χειρισµός του ‘πατώ και σύρω’ του ποντικιού. public void mouseDragged(MouseEvent me) {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
187
Graphics – Windows - GUI
// save coordinates mouseX = me.getX(); mouseY = me.getY(); movX = me.getX(); movY = me.getY(); msg = "*"; repaint(); } // χειρισµός της µετακίνησης του ποντικιού. public void mouseMoved(MouseEvent me) { // save coordinates movX = me.getX(); movY = me.getY(); repaint(0, 0, 100, 20); } // εµφάνιση µηνύµατος σε παράθυρο -applet. public void paint(Graphics g) { g.drawString(msg, mouseX, mouseY); g.drawString("Mouse at " + movX + ", " + movY, 0, 10); } }
Εργασίες Γραφικών Η AWT περιέχει πολλές µεθόδους που χειρίζονται τα γραφικά. Όλα τα σχήµατα σχεδιάζονται µέσα σε κάποιο παράθυρο που είναι είτε παράθυρο applet είτε παράθυρο µεµονωµένης εφαρµογής. Οι συντεταγµένες εκφράζονται σε pixels και στην κορυφή του παραθύρου είναι (0, 0). Η java χειρίζεται τα γραφικά µέσα από ένα γραφικό περιβάλλον που ορίζει η κλάση Graphics και υλοποιούνται µε δύο τρόπους : 9 Περνά τα γραφικά σε ένα applet – παράθυρο όταν καλούνται µέθοδοι όπως η paint() και update(). 9 Επιστρέφει γραφικά όταν καλείται η µέθοδος getGraphics() του Component.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
188
Graphics – Windows - GUI
Σχεδιασµός Γραµµών Η µέθοδος που χρησιµοποιείται είναι η drawLine(). Η γενική της µορφή είναι : Void drawLine(int startX, int startY, int endX, int endY) Όπου: StartX και startY, τα σηµεία εκκίνησης του σχεδιασµού της γραµµής και endX και endY, τα σηµεία τερµατισµού της γραµµής. Το χρώµα της γραµµής είναι το ίδιο µε το τρέχον. import java.awt.*; import java.applet.*; /* */ public class Lines extends Applet { public void paint(Graphics g) { g.drawLine(0, 0, 100, 100); g.drawLine(0, 100, 100, 0); g.drawLine(40, 25, 250, 180); g.drawLine(75, 90, 400, 400); g.drawLine(20, 150, 400, 40); g.drawLine(5, 290, 80, 19); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
189
Graphics – Windows - GUI
Σχεδιασµός Τετραγώνων Οι µέθοδοι που χρησιµοποιούνται είναι οι drawRect() και fillRect() που σχεδιάζουν η µεν πρώτη το περίγραµµα του τετραγώνου η δε δεύτερη τετράγωνο συµπληρωµένο όλο µε χρώµα. Η γενική των µορφή είναι : void drawRect(int top, int left, int width, int height) void fillRect(int top, int left, int width, int height) Για να σχεδιάσουµε τετράγωνο µε στρογγυλεµένες γωνίες χρησιµοποιούµε τις µεθόδους drawRoundRect() και fillRoundRect(). Η γενική µορφή των µεθόδων είναι : void
drawRoundRect(int
top,
int
left,
int
width,
int
int
left,
int
width,
int
height, int xDiam, int yDiam) void
fillRoundRect(int
top,
height, int xDiam, int yDiam) Όπου: xDiam και yDiam,
είναι οι διάµετροι των τόξων των γωνιών για τους άξονες χ και
ψ αντίστοιχα. •
Το παρακάτω παράδειγµα σχεδιάζει διάφορα τετράγωνα.
import java.awt.*; import java.applet.*; /* */ public class Rectangles extends Applet { public void paint(Graphics g) { g.drawRect(10, 10, 60, 50); g.fillRect(100, 10, 60, 50); g.drawRoundRect(190, 10, 60, 50, 15, 15); g.fillRoundRect(70, 90, 140, 100, 30, 40); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
190
Graphics – Windows - GUI
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο µε διάφορα τετράγωνα.
Σχεδιασµός Ελλείψεων και Κύκλων Οι µέθοδοι που χρησιµοποιούνται είναι οι drawOval() και fillOval(). Η γενική των µορφή είναι : void drawOval(int top, int left, int width, int height) void fillOval(int top, int left, int width, int height) Τα σχήµατα αυτά σχεδιάζονται σε νοητό τετράγωνο µε κορυφή τις top και left και µέγεθος width και height. •
Το παρακάτω παράδειγµα σχεδιάζει διάφορους κύκλους και ελλείψεις.
import java.awt.*; import java.applet.*; /* */ public class Ellipses extends Applet { public void paint(Graphics g) { g.drawOval(10, 10, 50, 50); g.fillOval(100, 10, 75, 50);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
191
Graphics – Windows - GUI
g.drawOval(190, 10, 90, 30); g.fillOval(70, 90, 140, 100); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Σχεδιασµός Τόξων Οι µέθοδοι που χρησιµοποιούνται είναι οι drawArc() και fillArc() που σχεδιάζουν η µεν πρώτη το περίγραµµα του τόξου η δε δεύτερη τόξο συµπληρωµένο όλο µε χρώµα. Η γενική των µορφή είναι : void drawArc(int top, int left, int width, int height, int startAngle, int sweepAngle) void fillArc(int top, int left, int width, int height, int startAngle, int sweepAngle) Τα τόξα αυτά σχεδιάζονται σε νοητό τετράγωνο µε κορυφή τις top και left και µέγεθος width και height. Το τόξο ξεκινά από την startAngle και τελειώνει στην sweepAngle.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
192
Graphics – Windows - GUI
Το παρακάτω παράδειγµα σχεδιάζει διάφορα τόξα.
import java.awt.*; import java.applet.*; /* */ public class Arcs extends Applet { public void paint(Graphics g) { g.drawArc(10, 40, 70, 70, 0, 75); g.fillArc(100, 40, 70, 70, 0, 75); g.drawArc(10, 100, 70, 80, 0, 175); g.fillArc(100, 100, 70, 90, 0, 270); g.drawArc(200, 80, 80, 80, 0, 180); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
193
Graphics – Windows - GUI
Σχεδιασµός Πολυγώνων Οι µέθοδοι που χρησιµοποιούνται είναι οι drawPolygon() και fillPolygon(). Η γενική των µορφή είναι : void drawPolygon(int x[], int y[], int numPoints) void fillPolygon(int x[], int y[], int numPoints) Όπου x[] και y[] είναι ο πίνακας µε της τιµές - σηµεία που θα ορίζουν το πολύγονο και η numPoints το πλήθος των τιµών – σηµείων. •
Το παρακάτω πρόγραµµα σχεδιάζει ένα πολύγωνο.
import java.awt.*; import java.applet.*; /* */ public class HourGlass extends Applet { public void paint(Graphics g) { int xpoints[] = {30, 200, 30, 200, 30}; int ypoints[] = {30, 30, 200, 200, 30}; int num = 5; g.drawPolygon(xpoints, ypoints, num); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω πολύγονο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
194
Graphics – Windows - GUI
Χρήση του χρώµατος Ο ορισµός χρώµατος στα γραφικά γίνεται µε την color(). Μορφές της color() είναι : color(int red, int green, int blue) color(int rgbValue) color(float red, float green, float blue) •
Στον πρώτο δοµητή τρεις ακέραιοι παράµετροι κάνουν µίξη των τριών χρωµάτων κόκκινου, πράσινου και µπλε. Οι τιµές πρέπει να είναι µεταξύ 0 – 255. Για παράδειγµα : color(255, 100, 100)
•
//ελαφρύ κόκκινο
Στον δεύτερο ο ακέραιος rgbValue θα περιέχει το τελικό αποτέλεσµα της µίξης των τριών χρωµάτων. Ο ακέραιος είναι οργανωµένος ως εξής: κόκκινο στα bits 16 –23, πράσινο στα bits 8 –15 και µπλε στα bits 0 –7.
•
Στον τρίτο δοµητή τρεις πραγµατικής τιµής παράµετροι κάνουν µίξη των τριών χρωµάτων κόκκινου, πράσινου και µπλε. Οι τιµές πρέπει να είναι µεταξύ 0.0 –1.0.
Μετά τον ορισµό του χρώµατος χρησιµοποιούµε τις µεθόδους setForeground() και setBackground() για τον ορισµό του χρώµατος του παρασκηνίου και υπόβαθρου αντίστοιχα. •
Στο παρακάτω παράδειγµα θα δούµε την χρήση του χρώµατος σε διάφορα σχήµατα.
import java.awt.*; import java.applet.*; /* */ public class ColorDemo extends Applet { // draw lines public void paint(Graphics g) { Color c1 = new Color(255, 100, 100); Color c2 = new Color(100, 255, 100);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
195
Graphics – Windows - GUI
Color c3 = new Color(100, 100, 255); g.setColor(c1); g.drawLine(0, 0, 100, 100); g.drawLine(0, 100, 100, 0); g.setColor(c2); g.drawLine(40, 25, 250, 180); g.drawLine(75, 90, 400, 400); g.setColor(c3); g.drawLine(20, 150, 400, 40); g.drawLine(5, 290, 80, 19); g.setColor(Color.red); g.drawOval(10, 10, 50, 50); g.fillOval(70, 90, 140, 100); g.setColor(Color.blue); g.drawOval(190, 10, 90, 30); g.drawRect(10, 10, 60, 50); g.setColor(Color.cyan); g.fillRect(100, 10, 60, 50); g.drawRoundRect(190, 10, 60, 50, 15, 15); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
196
Graphics – Windows - GUI
Ορισµός του τρόπου σχεδιασµού •
Η µέθοδος : void setXORMode(Color xorColor) ορίζει το χρώµα που θα φαίνεται πάντα επάνω στο σχέδιο.
•
Η µέθοδος : void setPaintMode() ορίζει την overwrite - κατάσταση επάνω στο σχέδιο.
•
Στο παρακάτω παράδειγµα θα δούµε πως ο ‘σταυρός’ ένδειξης του ποντικιού καλύπτει το υπάρχον σχήµα και την επαναφορά µε την setPaintMode().
import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ public class XOR extends Applet { int chsX=100, chsY=100; public XOR() { addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent me) { int x = me.getX(); int y = me.getY(); chsX = x-10; chsY = y-10; repaint(); } }); } public void paint(Graphics g) { g.drawLine(0, 0, 100, 100); g.drawLine(0, 100, 100, 0);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
197
Graphics – Windows - GUI
g.setColor(Color.blue); g.drawLine(40, 25, 250, 180); g.drawLine(75, 90, 400, 400); g.setColor(Color.green); g.drawRect(10, 10, 60, 50); g.fillRect(100, 10, 60, 50); g.setColor(Color.red); g.drawRoundRect(190, 10, 60, 50, 15, 15); g.fillRoundRect(70, 90, 140, 100, 30, 40); g.setColor(Color.cyan); g.drawLine(20, 150, 400, 40); g.drawLine(5, 290, 80, 19); g.setXORMode(Color.black); g.drawLine(chsX-10, chsY, chsX+10, chsY); g.drawLine(chsX, chsY-10, chsX, chsY+10); g.setPaintMode(); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράδειγµα.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
198
Προγραµµατισµός µε Java
Components
Components Είναι τα στοιχεία που επιτρέπουν την επικοινωνία µεταξύ των χρηστών και των εφαρµογών µας. Τα πιο συνηθισµένα είναι τα κουµπιά – buttons και οι ετικέτες – labels. Επίσης άλλα σηµαντικά συστατικά είναι τα : 9 Check boxes 9 Lists 9 Scroll bars 9 Choice Lists 9 Text editing
Προσθήκη και διαγραφή των Συστατικών - Components Για να χρησιµοποιηθεί ένα συστατικό πρώτα να δηµιουργηθεί και µετά να προστεθεί στην εφαρµογή µε την κλήση της µεθόδου add() που ορίζεται από την Container. Η γενική της µορφή είναι:
Component add(Component CompObj)
Το CompObj είναι το αντικείµενο που θα προστεθεί. Μόλις προστεθεί το συστατικό θα εµφανιστεί επάνω στο γονικό - παράθυρο. Για να διαγραφεί ένα συστατικό από το παράθυρο χρησιµοποιείται η µέθοδος remove() που ορίζεται επίσης από την Container. Η γενική της µορφή είναι: Component remove(Component CompObj) Η διαγραφή όλων των συστατικών γίνεται µε την κλήση της µεθόδου removeAll().
Συµβάντα Τα συστατικά κατά την χρήση των δηµιουργούν συµβάντα. Για παράδειγµα όταν πατάµε ένα κουµπί, τότε ένα συµβάν δηµιουργείται για να καταγράψει την ενέργεια αυτή. Με την δηµιουργία των συµβάντων πρέπει να δηµιουργηθούν και οι αντίστοιχοι
event
listeners
(τα
είδαµε
σε
προηγούµενο
κεφάλαιο)
που
ανταποκρίνονται σε αυτά.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
199
Προγραµµατισµός µε Java
Components
Ετικέτες - labels Είναι παθητικό συστατικό δηλαδή, δεν επιφέρει καµία επικοινωνία µε τον χρήστη. Είναι συστατικό του τύπου Label και εµφανίζει ένα string επάνω στο παράθυρο. Οι συνηθισµένοι δοµητές είναι: label() label(String str) label(String str, int how) Η πρώτη µορφή εµφανίζει ένα κενό string, η δεύτερη εµφανίζει το string – str µε αριστερή στοίχιση. Η τρίτη εµφανίζει ένα string αλλά µε τρόπο στοίχισης που καθορίζεται από τον ακέραιο how. Η how µπορεί να έχει τρεις τιµές τις σταθερές label.LEFT, label.RIGHT και label.CENTER. Λοιπές µέθοδοι της label: setText(),
αλλάζει το κείµενο της ετικέτας.
getText(),
επιστρέφει την τρέχουσα ετικέτα.
setAlignment(),
ορίζει ή αλλάζει την στοίχιση του string.
getAlignment(),
επιστρέφει την τρέχουσα στοίχηση.
Οι δοµητές των είναι : void setText(String str) String getText() void setAlignment(int how) int getAlignment() •
Το παρακάτω παράδειγµα δηµιουργεί τρεις ετικέτες και εµφανίζει τα αντίστοιχα µηνύµατα.
import java.awt.*; import java.applet.*; /* */ public class LabelDemo extends Applet {
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
200
Components
public void init() { Label one = new Label("One"); Label two = new Label("Two"); Label three = new Label("Three"); // προσθήκη των ετικετών στο παράθυρο. add(one); add(two); add(three); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Κουµπιά - buttons Είναι το συστατικό που χρησιµοποιούµε περισσότερο. Είναι αντικείµενο του τύπου Button και οι δύο δοµητές του είναι : button() button(String str)
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
201
Προγραµµατισµός µε Java
Components
Ο πρώτος δηµιουργεί ένα κουµπί χωρίς τίτλο και ο δεύτερος µε τίτλο. Μετά την δηµιουργία του κουµπιού µπορούµε να αλλάξουµε τον τίτλο µε την setLabel() ή να πάρουµε τον τίτλο του µε την getLabel(). Η γενική µορφή των µεθόδων είναι: void setLabel(String str) String getLabel() •
Όταν πατάµε το κουµπί δηµιουργείται ένα συµβάν που συλλαµβάνεται από τον αντίστοιχο event listener που έχει δηλωθεί από πριν. Ο listener αυτός ενεργοποιεί το Action Listener – περιβάλλον. Το Action Listener περιέχει την µέθοδο actionPerformed() που λαµβάνει το συµβάν. To αντικείµενο Action Event που δηµιουργείται στέλνεται σαν παράµετρος στη µέθοδο actionPerformed(). Στο παρακάτω παράδειγµα θα δούµε τη δηµιουργία και χρήση τριών κουµπιών. Κάθε φορά που πατάµε το κουµπί θα εµφανίζεται και το αντίστοιχο µήνυµα. Στο παράδειγµα αυτό ο τίτλος του κάθε κουµπιού χρησιµοποιείται για να ανιχνευθεί το πλήκτρο που πατήθηκε. Ο τίτλος του κουµπιού
ανιχνεύεται
αντικειµένου
Action
από Event
την
µέθοδο
που
getActionCommand()
στέλνεται
σαν
παράµετρος
του στην
actionPerformed(). import java.awt.*; import java.awt.event.*; import java.applet.*; /*
*/ public class ButtonDemo extends Applet implements ActionListener { String msg = ""; Button yes, no, maybe; public void init() { yes = new Button("Yes"); no = new Button("No"); maybe = new Button("Undecided"); add(yes); add(no);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
202
Components
add(maybe); yes.addActionListener(this); no.addActionListener(this); maybe.addActionListener(this); } public void actionPerformed(ActionEvent ae) { String str = ae.getActionCommand(); if(str.equals("Yes")) { msg = "You pressed Yes."; } else if(str.equals("No")) { msg = "You pressed No."; } else { msg = "You pressed Undecided."; } repaint(); } public void paint(Graphics g) { g.drawString(msg, 6, 100); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
203
Components
Μία παραλλαγή της χρήσης των πλήκτρων είναι η παρακάτω όπου το πάτηµα του κάθε κουµπιού ανιχνεύεται από το τρέχον αντικείµενο µε την χρήση της µεθόδου getSource(). Για να εκτελεσθεί η ανωτέρω µέθοδος πρέπει να κρατάµε λίστα των αντικειµένων που προσθέτουµε στο παράθυρο.
import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ public class ButtonList extends Applet implements ActionListener { String msg = ""; Button bList[] = new Button[3]; public void init() { Button yes = new Button("Yes"); Button no = new Button("No"); Button maybe = new Button("Undecided"); // αποθήκευση αναφοράς για το κάθε κουµπί που δηµιουργείται bList[0] = (Button) add(yes); bList[1] = (Button) add(no); bList[2] = (Button) add(maybe); // δήλωση για να λαµβάνουµε τα action events for(int i = 0; i < 3; i++) { bList[i].addActionListener(this); } } public void actionPerformed(ActionEvent ae) { for(int i = 0; i < 3; i++) { if(ae.getSource() == bList[i]) { msg = "You pressed " + bList[i].getLabel(); }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
204
Components
} repaint(); } public void paint(Graphics g) { g.drawString(msg, 6, 100); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε ακριβώς το ίδιο αποτέλεσµα.
Χρήση των Check Boxes Είναι αντικείµενο της κλάσης Checkbox και χρησιµοποιείται σαν διακόπτης on | off. Αποτελείται από ένα τίτλο και ένα µικρό κουτάκι στο οποίο µαρκάρουµε ή ξεµαρκάρουµε µε το ποντίκι. Τέτοια Checkbox µπορούµε να έχουµε µεµονωµένα ή σε γκρουπ. Οι δοµητές του είναι: Checkbox() Checkbox(String str) Checkbox(String str, boolean on) Checkbox(String str, boolean on, CheckboxGroup cbGroup) Checkbox(String str, CheckboxGroup cbGroup, boolean on) Η πρώτη µορφή δηµιουργεί ένα συστατικό χωρίς ετικέτα και το κουτάκι του δεν είναι µαρκαρισµένο. Η δεύτερη µορφή δηµιουργεί ένα συστατικό µε ετικέτα - str και το κουτάκι του δεν είναι µαρκαρισµένο. Η τρίτη µορφή µαρκάρει και το κουτάκι. Αν το on είναι αληθές, τότε το κουτάκι είναι µαρκαρισµένο. Στην τέταρτη µορφή καθορίζεται και το όνοµα του γκρουπ
στο οποίο ανήκει. Για να λάβουµε την
κατάσταση του συστατικού χρησιµοποιούµε την getState() και για να την αλλάξουµε την setState(). Λαµβάνουµε τον τίτλο του συστατικού µε την getLabel() και τον αλλάζουµε µε την setLabel(). Οι µέθοδοι είναι οι παρακάτω: boolean getState() void setState(boolean on) String getLabel() void setLabel(String str) Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
205
Components
Όταν µαρκάρουµε ή ξεµαρκάρουµε ένα Checkbox δηµιουργείται ένα συµβάν που συλλαµβάνεται κατά τα γνωστά από τον αντίστοιχο listener που παρέχει το ItemListener – περιβάλλον που µε την σειρά του ορίζει την µέθοδο itemstateChange(). Ένα αντικείµενο ItemEvent στέλνεται σαν παράµετρος σε αυτή την µέθοδο. Στο παρακάτω παράδειγµα θα δηµιουργήσουµε τέσσερα CheckBoxes και όταν µαρκάρουµε κάποιο από αυτά θα εµφανίζεται το αντίστοιχο µήνυµα.
import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ public class CheckboxDemo extends Applet implements ItemListener { String msg = ""; Checkbox Win98, winNT, solaris, mac; public void init() { Win98 = new Checkbox("Windows 98", null, true); winNT = new Checkbox("Windows NT"); solaris = new Checkbox("Solaris"); mac = new Checkbox("MacOS"); add(Win98); add(winNT); add(solaris); add(mac); Win98.addItemListener(this); winNT.addItemListener(this); solaris.addItemListener(this); mac.addItemListener(this); } public void itemStateChanged(ItemEvent ie) { repaint(); }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
206
Components
// εµφάνιση της τρέχουσας κατάστασης των check boxes. public void paint(Graphics g) { msg = "Current state: "; g.drawString(msg, 6, 80); msg = "
Windows 98: " + Win98.getState();
g.drawString(msg, 6, 100); msg = "
Windows NT: " + winNT.getState();
g.drawString(msg, 6, 120); msg = "
Solaris: " + solaris.getState();
g.drawString(msg, 6, 140); msg = "
MacOS: " + mac.getState();
g.drawString(msg, 6, 160); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
•
Στην παρακάτω παραλλαγή θα οµαδοποιήσουµε τα Checkboxes σε γκρουπ. Εδώ θα δηλώσουµε το όνοµα του γκρουπ. Θα ανιχνεύσουµε το τρέχον Checkboxe µέσα στο γκρουπ µε την getSelectedCheckbox() ή
θα το
ορίσουµε µε την setSelectedCheckbox(). Τα συστατικά στην άσκηση αυτή έγιναν Radiobuttons.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
207
Components
import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ public class CBGroup extends Applet implements ItemListener { String msg = ""; Checkbox Win98, winNT, solaris, mac; CheckboxGroup cbg; public void init() { cbg = new CheckboxGroup(); Win98 = new Checkbox("Windows 98", cbg, true); winNT = new Checkbox("Windows NT", cbg, false); solaris = new Checkbox("Solaris", cbg, false); mac = new Checkbox("MacOS", cbg, false); add(Win98); add(winNT); add(solaris); add(mac); Win98.addItemListener(this); winNT.addItemListener(this); solaris.addItemListener(this); mac.addItemListener(this); } public void itemStateChanged(ItemEvent ie) { repaint(); } // εµφάνιση της τρέχουσας κατάστασης των check boxes. public void paint(Graphics g) { msg = "Current selection: "; msg += cbg.getSelectedCheckbox().getLabel(); g.drawString(msg, 6, 100); } }
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
208
Components
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Χρήση των πεδίων - Edit Η κλάση TextField παρέχει µία περιοχή απλής γραµµής για είσοδο κειµένου που ονοµάζεται συστατικό edit. Ο χρήστης εισάγει κείµενο που µπορεί να χειριστεί στην συνέχεια µε cut - copy – paste. Είναι υποκλάση της TextComponent. Οι δοµητές των πεδίων κειµένου είναι : TextField() TextField(int numChars) TextField(String str) TextField(String str, int numChars) Η πρώτη δηµιουργεί ένα κενό πεδίο, η δεύτερη ένα πεδίο µε numCharsχαρακτήρες εύρος, η τρίτη ένα πεδίο µε ένα string σε αυτό και τέλος η τέταρτη µε string και προκαθορισµένο εύρος. Οι µέθοδοι που χρησιµοποιούνται είναι οι : String getText(), για να λάβουµε το string που περιέχεται στο πεδίο. void setText(String str), για να αλλάξουµε το string του πεδίου. String getSelectedText(),επιστρέφει επιλεγµένο κείµενο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
209
Προγραµµατισµός µε Java
void
Select(int
startIndex,
Components
int
endIndex
),επιστρέφει
επιλεγµένο κείµενο που αρχίζει από την τιµή startIndex και τελειώνει στην τιµή endIndex. boolean isEditable(), επιστρέφει true ή false ανάλογα µε το αν επιτρέπεται η µεταβολή του κειµένου ή όχι αντίστοιχα. void
setEditable(boolean
canEdit), ορίζει αν το κείµενο θα
µεταβάλλεται ή όχι. void setEchoChar(char ch), αποκρύπτονται οι εισερχόµενοι χαρακτήρες και συνέχεια εµφανίζεται ο ίδιος χαρακτήρας για παράδειγµα ο * (είσοδος password). boolean
echoCharIsSet(),επιστρέφει true ή false ανάλογα µε το αν
επιτρέπεται η προηγούµενη κατάσταση ή όχι. void getEchoChar(),επιστρέφει τον χαρακτήρα που χρησιµοποιείται για την απόκρυψη. •
Όταν εισάγεται το κείµενο τα πλήκτρα δεν λειτουργούν εκτός βέβαια από τα βελάκια και το πάτηµα του ENTER που προκαλεί συµβάν όταν πατηθεί. Το παρακάτω παράδειγµα δηµιουργεί το κλασικό παράθυρο εισόδου του ονόµατος ενός χρήστη και του password.
import java.awt.*; import java.awt.event.*; import java.applet.*; /*
*/ public class TextFieldDemo extends Applet implements ActionListener { TextField name, pass; public void init() { Label namep = new Label("Name: ", Label.RIGHT); Label passp = new Label("Password: ", Label.RIGHT);
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
210
Components
name = new TextField(12); pass = new TextField(8); pass.setEchoChar('?'); add(namep); add(name); add(passp); add(pass); // δήλωση για τη λήψη των action events name.addActionListener(this); pass.addActionListener(this); } // Ο χρήστης πατά Enter. public void actionPerformed(ActionEvent ae) { repaint(); } public void paint(Graphics g) { g.drawString("Name: " + name.getText(), 6, 60); g.drawString("Selected text in name: " + name.getSelectedText(), 6, 80); g.drawString("Password: " + pass.getText(), 6, 100); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
211
Προγραµµατισµός µε Java
Components
Χρήση των περιοχών κειµένου – memo box Για είσοδο κειµένου περισσοτέρων γραµµών η java παρέχει την TextArea που είναι ένας µικρός και πρωτόγονος editor. Οι δοµητές της είναι : TextArea() TextArea(int numLines, int numChars) TextArea(String str) TextArea(String str, int numLines, int numChars) TextArea(String
str,
int
numLines,
int
numChars,int
sBars) SBars, είναι µία από τις τέσσερις τιµές για τις µπάρες κύλισης. Εκτός από τις ήδη γνωστές µεθόδους getText(),
setText(),
getSelectedText(),
select(), isEditable και setEditable() ισχύουν και οι παρακάτω : void append(String str), προσθέτει το string στο τέλος του κειµένου. void insert(String str, int index), εισάγει το string στην θέση index. void
replaceRange(String
str,
int
startindex,
int
endindex), αντικαθιστά τους χαρακτήρες από την startindex έως την endindex µε το string-str. •
Στο παρακάτω παράδειγµα θα δούµε την δηµιουργία και χρήση µιας TextArea.
import java.awt.*; import java.applet.*; /* */ public class TextAreaDemo extends Applet { public void init() { String val = "There are two ways of constructing " + "a software design.\n" + "One way is to make it so simple\n" +
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
212
Components
"that there are obviously no deficiencies.\n" + "And the other way is to make it so complicated\n" + "that there are no obvious deficiencies.\n\n" + "
-C.A.R. Hoare\n\n" +
"There's an old story about the person who wished\n" + "his computer were as easy to use as his telephone.\n" + "That wish has come true,\n" + "since I no longer know how to use my telephone.\n\n" + "
-Bjarne Stroustrup, AT&T, (inventor of C++)";
TextArea text = new TextArea(val, 10, 30); add(text); } }
•
Στο παρακάτω παράδειγµα θα δούµε την δηµιουργία και χρήση µιας TextArea.
Συστατικά Επιλογών - Choice Μέθοδοι : void
addItem(String
name),προσθήκη
του string στην λίστα των
επιλογών. void add(String name), προσθήκη του string στην λίστα των επιλογών. String getSelected Item(), επιστρέφει το όνοµα της τρέχουσας επιλογής. Int getSelected Index(), επιστρέφει τον αριθµό της επιλογής. Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
213
Components
int getItemCount(), λαµβάνουµε το πλήθος των επιλογών της λίστας. void select(int index), ορίζουµε ποια θα είναι η τρέχουσα επιλογή γράφοντας τον αριθµό index. void select(String name), ορίζουµε ποια θα είναι η τρέχουσα επιλογή γράφοντας την ίδια την επιλογή. Μόλις επιλέξουµε µία επιλογή δηµιουργείται ένα συµβάν που συλλαµβάνεται από τoν αντίστοιχο listener που έχει από προηγουµένως ορισθεί. Στην συνέχεια καλείται το περιβάλλον ItemListener που ορίζει τη µέθοδο itemStateChange() που λαµβάνει σαν παράµετρο το αντικείµενο ItemEvent του συµβάντος που δηµιουργείται. Στο παρακάτω παράδειγµα θα δηµιουργήσουµε δύο λίστες επιλογών, µία για επιλογή του λειτουργικού συστήµατος και µία για την επιλογή πλοηγού - browser. import java.awt.*; import java.awt.event.*; import java.applet.*; /* */ public class ChoiceDemo extends Applet implements ItemListener { Choice os, browser; String msg = ""; public void init() { os = new Choice(); browser = new Choice(); // προσθήκη στη λίστα των λειτουργικών συστηµάτων os.add("Windows 98"); os.add("Windows NT"); os.add("Solaris"); os.add("MacOS"); // προσθήκη στη λίστα των πλοηγών browser.add("Netscape 1.1"); browser.add("Netscape 2.x");
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
214
Components
browser.add("Netscape 3.x"); browser.add("Netscape 4.x"); browser.add("Internet Explorer 2.0"); browser.add("Internet Explorer 3.0"); browser.add("Internet Explorer 4.0"); browser.add("Lynx 2.4"); browser.select("Netscape 4.x"); // προσθέτουµε τις δύο λίστες στο παράθυρο add(os); add(browser); // δήλωση για τη λήψη των συµβάντων os.addItemListener(this); browser.addItemListener(this); } public void itemStateChanged(ItemEvent ie) { repaint(); } // εµφάνιση της τρέχουσας επιλογής. public void paint(Graphics g) { msg = "Current OS: "; msg += os.getSelectedItem(); g.drawString(msg, 6, 120); msg = "Current Browser: "; msg += browser.getSelectedItem(); g.drawString(msg, 6, 140); } }
•
Αν εκτελέσουµε το πρόγραµµα θα πάρουµε το παρακάτω παράθυρο.
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Παναγιώτης Σφέτσος,
215
Ιωάννης Σταµέλος,
Components
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java •
216
Βιβλιογραφία
The Complete Reference, Java 2, Third Edition, Patrick Naughton and Herbert Schildt, Osborne, Mc Graw Hill, 1999.
•
JAVA UNLEASHED, Second Edition, Michael Morrison, Sams Publication, 1997.
•
The Java Tutorial Second Edition, SUN Microsystems, 2 / 2000.
•
Internet material
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Πίνακας Περιεχοµένων
ΠΕΡΙΓΡΑΦΗ
ΣΕΛΙ∆Α
Εισαγωγή
1
ΚΕΦΑΛΑΙΟ 1ο – Το πρώτο µας πρόγραµµα Οι εργασίες εγκατάστασης Το πρώτο µας Πρόγραµµα Μεταγλώττιση και εκτέλεση του προγράµµατος H γενική δοµή του προγράµµατος Μία δεύτερη µατιά στο πρόγραµµα Ο κύκλος Γράψε, Μεταγλώττισε, Εκτέλεσε.. Παραλλαγή του προγράµµατος Hello
2 2 4 5 6 8 8
ΚΕΦΑΛΑΙΟ 2ο – ∆εδοµένα – Τελεστές - Μεταβλητές Αρχικοί τύποι δεδοµένων Ακέραιοι και ∆εκαδικοί Ακρίβεια δεκαδικών αριθµών Ο αρχικός τύπος char Ο αρχικός τύπος boolean H κλάση string Αριθµητικοί τελεστές ∆ήλωση Σταθερών (Constants) Μεταβλητές (variables) Ονόµατα Μεταβλητών Ασκήσεις µε χρήση Μεταβλητών Εκτέλεση Πράξεων Κατανόηση της χρήσης των τελεστών Ανάλυση της εκτέλεσης αριθµητικών πράξεων Πρόσθεση και αφαίρεση ακεραίων – Int Πρόσθεση και αφαίρεση πραγµατικών – Double Πολλαπλασιασµός και ∆ιαίρεση ακεραίων Ο Τελεστής - υπόλοιπο διαίρεσης (%) Πράξεις µε µεικτούς τύπους Πράξεις µε boolean – τελεστές String – τελεστές (συνένωση - concatenation) Bitwise - λογικοί τελεστές Μετατροπές τύπων δεδοµένων Type Conversion and Casting Λοιπές ασκήσεις πράξεων και τύπων δεδοµένων Η ανάθεση τιµής – assignment Ο τελεστής ? Προτεραιότητα εκτέλεσης πράξεων Ασκήσεις
9 9 10 10 10 10 11 11 12 12 12 13 13 16 16 17 18 19 20 22 23 23 26 26 28 30 31 32 33
ΚΕΦΑΛΑΙΟ 3ο – Εντολές Ελέγχου Λογικοί τελεστές – boolean Εντολή - if Φωλιασµένες if (nested)
34 34 34
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Πίνακας Περιεχοµένων
H κλιµακωτή εντολή if – else if Εντολή – switch Φωλιασµένες switch Εντολές επανάληψης Eντολή – for Φωλιασµένες for Εντολή – while Εντολή do – while Ο διαχωριστής comma στη for – θηλιά Εντολές εξόδου Η χρήση της break Εντολή – continue Εντολή – return
35 36 37 37 38 40 41 42 43 44 44 47 49
ΚΕΦΑΛΑΙΟ 4ο – Είσοδος -Έξοδος (Ι/Ο) Εργασίες Input – Output ( I / O) Οι κλάσεις - Byte stream Οι κλάσεις - Character stream ∆ιάβασµα από την κονσόλα (Input) Άσκηση µε µενού επιλογών Είσοδος χαρακτήρων µε χρήση της append Είσοδος String Είσοδος αριθµών Μετατροπές εισαγοµένων τιµών Έξοδος στην κονσόλα (Output) Η κλάση PrintWriter Ασκήσεις εισόδου – επαναλήψεων Ανακατεύθυνση της εξόδου των αποτελεσµάτων Ανακατεύθυνση της εισόδου των δεδοµένων Ταυτόχρονη ανακατεύθυνση εισόδου – εξόδου Είσοδος αριθµών από αρχείο
50 51 51 51 53 54 55 56 58 59 59 60 69 70 72 72
ΚΕΦΑΛΑΙΟ 5ο – Εξαιρέσεις - Exceptions Χειρισµός των Εξαιρέσεων Throw Finally
78 80 80
ΚΕΦΑΛΑΙΟ 6ο – Πίνακες – Arrays Εισαγωγή Ορισµοί και σύνταξη Παραδείγµατα µε πίνακες Πίνακες πολλαπλών διαστάσεων Χρήση Πίνακα ως παραµέτρου
85 85 86 87 93
ΚΕΦΑΛΑΙΟ 7ο – Κλάσεις - Αντικείµενα Κλάσεις Ορισµός της Κλάσης
97 97
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Πίνακας Περιεχοµένων
Ορισµός των αντικειµένων – Τελεστής new Ορισµός των Μεθόδων Επιστροφή τιµής Μεθόδου Μέθοδοι που δέχονται παραµέτρους ∆οµητές – Constructors Η δεσµευµένη λέξη – this Συλλογή σκουπιδιών (Garbage collection) Η µέθοδος Finalize() Έλεγχος Προσπέλασης (Access control) Μέθοδοι Υπερφόρτωσης (Overloading Methods) Υπερφόρτωση ∆οµητών Χρήση των αντικειµένων σαν παράµετροι Μια δεύτερη µατιά στο πέρασµα των παραµέτρων Επιστροφή αντικειµένων Αναδροµή (Recursion) Ο ορισµός static Οι πίνακες σαν αντικείµενα Εστιασµένες κλάσεις Κληρονοµικότητα (Inheritance) Χρήση της λέξης super Χρήση της κλάσης abstract Απαγόρευση κληρονοµικότητας Η κλάση Object Το string σαν αντικείµενο Ασκήσεις κλάσεων
99 100 101 102 104 106 107 107 108 111 114 116 117 120 121 123 124 126 127 131 137 139 139 140 140
ΚΕΦΑΛΑΙΟ 8ο – Χειρισµός των Αρχείων ∆ιάβασµα και γράψιµο αρχείων
146
ΚΕΦΑΛΑΙΟ 9ο – Χειρισµός των Strings Η κλάση String Συνένωση δύο string Μέθοδοι της string Πίνακες µε strings Η τιµή null Οι σηµαντικότεροι δοµητές και µέθοδοι των strings Χαρακτήρες ελέγχου των αντικειµένων string Ασκήσεις επί των string ∆ηµιουργία ενός string από άλλο String από υποσύνολο χαρακτήρων αποθηκευµένων σε πίνακα Χρήση της συνένωσης για την αποφυγή δηµιουργίας µεγάλων γραµµών κειµένου Χρήση της getChars() Σύγκριση µε τις equals() και equalsIgnoreCase() Ταξινόµηση φυσαλίδας –bubble για strings Χρήση της indexOf() και lastIndexOf() Αντικατάσταση Substring Χρήση της trim() για σωστή εκτέλεση των εντολών Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
152 152 153 154 155 155 156 157 157 157 157 157 158 158 159 160 160
Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Πίνακας Περιεχοµένων
Χρήση των toUpperCase() και toLowerCase() Το length και η capacity του StringBuffer Χρήση των charAt() και setCharAt() Χρήση της append(). Χρήση της insert() Χρήση της reverse()για αντιστροφή string σε StringBuffer Χρήση της delete() και deleteCharAt() Χρήση της replace() Πέρασµα παραµέτρων κατά την εκτέλεση του προγράµµατος
161 161 162 162 162 163 163 163 164
ΚΕΦΑΛΑΙΟ 10ο – Applets Βασικές αρχές Μέθοδοι Ζωγραφικής Σχεδιασµός κύκλου Σχεδιασµός τετραγώνου Σχεδιασµός γραµµής
165 167 167 168 168
ΚΕΦΑΛΑΙΟ 11ο – Graphics – Windows - GUI Abstract Window Toolkit (AWT) Ιεραρχία των παραθύρων Η κλάση Component Container Window Frame Canvas H εργασία µε τα Frame - παράθυρα Ορισµός των διαστάσεων του παραθύρου Εµφάνιση και απόκρυψη παραθύρου Ορισµός του τίτλου παραθύρου Κλείσιµο παραθύρου ∆ηµιουργία GUI – περιβάλλοντος Event Listeners H κλάση WindowAdapter Εργασίες Γραφικών Σχεδιασµός Γραµµών Σχεδιασµός Τετραγώνων Σχεδιασµός Ελλείψεων και κύκλων Σχεδιασµός Τόξων Σχεδιασµός Πολυγώνων Χρήση του χρώµατος Ορισµός του τρόπου σχεδιασµού Ορισµός του τρόπου σχεδιασµού
173 173 173 173 174 174 174 174 174 175 175 175 178 178 178 187 188 189 189 191 193 194 196 196
ΚΕΦΑΛΑΙΟ 12ο – C o m p o n e n t s Components Προσθήκη και διαγραφή Συστατικών Συµβάντα Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
198 198 198 Θεσσαλονίκη Φεβρουάριος 2003
Προγραµµατισµός µε Java
Πίνακας Περιεχοµένων
Ετικέτες - labels Κουµπιά - buttons Χρήση των Check Boxes Χρήση των πεδίων - Edit Χρήση των περιοχών κειµένου – memo box Συστατικά επιλογών Choice
198 200 204 208 211 212
ΒΙΒΛΙΟΓΡΑΦΙΑ
216
Παναγιώτης Σφέτσος,
Ιωάννης Σταµέλος,
Θεσσαλονίκη Φεβρουάριος 2003