Στην Java, οι μεταβλητές είναι προσβάσιμες μόνο μέσα στην περιοχή που δημιουργούνται. Αυτό ονομάζεται scope (εμβέλεια).
Υπάρχουν δύο επίπεδα εμβέλειας στην Java:
- Επίπεδο μεθόδου (local scope)
- Επίπεδο κλάσης (class scope)
Το επίπεδο μεθόδου ορίζει την εμβέλεια μιας μεταβλητής σε μια μέθοδο. Μια μεταβλητή που δηλώνεται μέσα σε μια μέθοδο είναι προσβάσιμη μόνο στην μέθοδο αυτή και δεν μπορεί να χρησιμοποιηθεί σε άλλες μεθόδους.
Το επίπεδο κλάσης ορίζει την εμβέλεια μιας μεταβλητής σε μια κλάση. Μια μεταβλητή που δηλώνεται μέσα σε μια κλάση είναι προσβάσιμη από οποιοδήποτε σημείο της κλάσης.
Παρακάτω είναι ένα παράδειγμα του επιπέδου μεθόδου:
public class Example { public static void main(String[] args) { // επίπεδο μεθόδου int x = 10; System.out.println(x); // 10 } }
Στο παραπάνω παράδειγμα, η μεταβλητή x
έχει επίπεδο μεθόδου, καθώς ορίζεται μέσα στη μέθοδο main()
. Η μεταβλητή x
είναι προσβάσιμη μόνο μέσα στη μέθοδο main()
.
Ένα block of code αναφέρεται σε όλο τον κώδικα μεταξύ των αγκυλών {}.
Οι μεταβλητές που δηλώνονται μέσα σε block of code είναι προσβάσιμες μόνο από τον κώδικα μεταξύ των αγκυλών, ο οποίος ακολουθεί τη γραμμή στην οποία δηλώθηκε η μεταβλητή:
public class Example { public static void main(String[] args) { // επίπεδο μεθόδου int x = 10; if (x == 10) { // block επίπεδου μεθόδου int y = 20; System.out.println(x + y); // 30 } // System.out.println(y); // σφάλμα } }
Στο παραπάνω παράδειγμα, η μεταβλητή y
έχει block scope, καθώς ορίζεται μέσα στο block εντολών της συνθήκης if
. Η μεταβλητή y
είναι προσβάσιμη μόνο μέσα στο block εντολών της συνθήκης if
και δεν μπορεί να χρησιμοποιηθεί έξω από αυτό. Επίσης, προσέξτε ότι αν προσπαθήσετε να εκτυπώσετε την μεταβλητή y
έξω από το block εντολών της συνθήκης if
, θα λάβετε ένα σφάλμα στον μεταγλωττιστή (compiler error).
[adinserter block=”2″]
Η αναδρομή (recursion) είναι η τεχνική της κλήσης μιας συνάρτησης από μέσα της ίδιας της συνάρτησης. Αυτή η τεχνική παρέχει έναν τρόπο για την επίλυση πολύπλοκων προβλημάτων, διαιρώντας τα σε απλούστερα υποπροβλήματα που είναι πιο εύκολο να λυθούν.
Η αναδρομή μπορεί να είναι λίγο δύσκολη στην κατανόηση. Ο καλύτερος τρόπος για να καταλάβετε πώς λειτουργεί είναι να πειραματιστείτε με αυτήν.
Ένα παράδειγμα της αναδρομής είναι η υλοποίηση του αλγορίθμου του παραγοντικού με αναδρομή:
public class Example { public static int factorial(int n) { if (n == 1) { return 1; } else { return n * factorial(n - 1); } } public static void main(String[] args) { int result = factorial(5); System.out.println(result); // 120 } }
Στο παραπάνω παράδειγμα, η μέθοδος factorial()
καλεί τον εαυτό της με μικρότερη τιμή n
μέχρι να φτάσει στην τιμή 1, όπου η συνθήκη if
θα επιστρέψει την τιμή 1 και η αναδρομή θα τερματιστεί. Η μέθοδος factorial()
υπολογίζει το παραγοντικό του αριθμού n
ως το γινόμενο του n
με το παραγοντικό του n-1
. Η αναδρομή στη συγκεκριή περίπτωση συνεχίζει να καλεί την factorial()
μέθοδο μέχρι να επιτευχθεί η τερματική συνθήκη (n = 1) και τότε η αναδρομή σταματά.
Η αναδρομή χρησιμοποιείται συχνά στην Java για την επίλυση προβλημάτων όπως η αναζήτηση δέντρων, η διαδικασία ταξινόμησης και άλλα. Ωστόσο, η χρήση της αναδρομής πρέπει να γίνεται με προσοχή, καθώς μπορεί να οδηγήσει σε ατέρμονες κλήσεις και σε απρόβλεπτη συμπεριφορά του κώδικα.
Η προσθήκη δύο αριθμών είναι εύκολη, αλλά η προσθήκη μιας σειράς αριθμών είναι πιο περίπλοκη. Στο παρακάτω παράδειγμα, χρησιμοποιείται η αναδρομή για την προσθήκη μιας σειράς αριθμών διαιρώντας το πρόβλημα σε απλούστερες προσθέσεις δύο αριθμών:
public class Example { public static int sum(int start, int end) { if (end > start) { return end + sum(start, end - 1); } else { return start; } } public static void main(String[] args) { int result = sum(1, 5); System.out.println(result); // 15 } }
Στο παραπάνω παράδειγμα, η μέθοδος sum()
καλεί τον εαυτό της με μικρότερη τιμή end
μέχρι να φτάσει στην τιμή start
. Η αναδρομή συνεχίζεται μέχρι το end
να είναι ίσο ή μικρότερο από το start
. Σε αυτό το σημείο, η αναδρομή σταματά και η μέθοδος επιστρέφει την τιμή του start
. Η συνάρτηση υπολογίζει το άθροισμα των αριθμών από το start
μέχρι το end
συνδυάζοντας απλές προσθέσεις δύο αριθμών σε κάθε κλήση της αναδρομής.
Η έξοδος που θα εμφανιστεί στην οθόνη μετά την εκτέλεση του παραπάνω κώδικα θα είναι:
15
Αυτό συμβαίνει διότι η μέθοδος sum(1, 5)
υπολογίζει το άθροισμα των αριθμών από το 1 μέχρι το 5, συνεχίζοντας την αναδρομή μέχρι να φτάσει στον τελικό αριθμό και να επιστρέψει το αποτέλεσμα.
Όπως και με τα loops, οι αναδρομικές συναρτήσεις μπορούν να αντιμετωπίσουν το πρόβλημα της ατέρμονης αναδρομής. Η ατέρμονη αναδρομή συμβαίνει όταν η συνάρτηση δεν σταματά να καλεί τον εαυτό της ποτέ. Κάθε αναδρομική συνάρτηση θα πρέπει να έχει μια συνθήκη τερματισμού, η οποία είναι η συνθήκη όπου η συνάρτηση σταματά να καλεί τον εαυτό της. Στο προηγούμενο παράδειγμα, η συνθήκη τερματισμού είναι όταν η παράμετρος k γίνεται ίση με 0.
[adinserter block=”3″]
Είναι χρήσιμο να δούμε διάφορα παραδείγματα για να κατανοήσουμε καλύτερα τον συγκεκριμένο έννοια. Σε αυτό το παράδειγμα, η συνάρτηση προσθέτει μια σειρά αριθμών από ένα αρχικό σημείο έως ένα τελικό σημείο. Η συνθήκη τερματισμού για αυτή την αναδρομική συνάρτηση είναι όταν το τελικό σημείο δεν είναι μεγαλύτερο από το αρχικό σημείο:
public class Example { public static int sum(int start, int end) { if (end > start) { return end + sum(start, end - 1); } else { return start; } } public static void main(String[] args) { int result = sum(1, 5); System.out.println(result); // 15 } }
Στο παραπάνω παράδειγμα, η συνάρτηση sum()
καλεί τον εαυτό της με μικρότερη τιμή end
μέχρι να φτάσει στην τιμή start
. Η αναδρομή συνεχίζεται μέχρι το end
να είναι ίσο ή μικρότερο από το start
. Σε αυτό το σημείο, η αναδρομή σταματά και η μέθοδος επιστρέφει την τιμή του start
. Η συνάρτηση υπολογίζει το άθροισμα των αριθμών από το start
μέχρι το end
συνδυάζοντας απλές προσθέσεις δύο αριθμών σε κάθε κλήση της αναδρομής.
Εάν η συνθήκη τερματισμού δεν επιτευχθεί ποτέ, η αναδρομή θα συνεχιστεί για πάντα, προκαλώντας ένα σφάλμα ατέρμονης αναδρομής. Για να αποφύγετε το σφάλμα αυτό, πρέπει να διασφαλίσετε ότι η συνθήκη τερματισμού θα επιτευχθεί σε κάθε κλήση της αναδρομής.