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