JAVA ΕΝΟΤΗΤΑ 17 – ACCESS SPECIFIERS AND GETTER/SETTER METHODS

 


ΕΙΣΑΓΩΓΗ

Στο σημερινό δωρεάν μάθημα Java θα ασχοληθούμε με τους access specifiers και πως αυτοί μας οδηγούν στο να χρησιμοποιήσουμε getter και setter μεθόδους.

ATM STUDY CASE

Σε κάθε μεταβλητή ή μέθοδο που έχουμε δημιουργήσει μέχρι τώρα, έχουμε βάλει την λέξη public μπροστά από τον ορισμό τους. Η λέξη κλειδί public μας επιτρέπει να έχουμε πρόσβαση και να χρησιμοποιήσουμε τις instance μεταβλητές και μεθόδους μιας κλάσης, είτε βρισκόμαστε στο ίδιο πακέτο με την κλάση από την οποία δημιουργούμε το αντικείμενο είτε όχι. Η χρήση του public δεν είναι η καλύτερη και ασφαλέστερη προγραμματιστική προσέγγιση γιατί μπορεί να μας προκαλέσει πολλά προβλήματα κυρίως όταν εισάγουμε τιμές στο πρόγραμμα μας. Ας δούμε όμως ένα παράδειγμα μέσα από το οποίο θα κατανοήσουμε καλύτερα το πρόβλημα και πως θα το λύσουμε με τις getter και setter μεθόδους.

Στο σημερινό δωρεάν μάθημα Java, θα ασχοληθούμε με ένα πρόγραμμα το οποίο κάνει simulation ένα ATM μηχάνημα από το οποίο μπορούμε να κάνουμε κατάθεση (deposit) ή ανάληψη (withdraw) χρημάτων. Θα ξεκινήσουμε γράφοντας το κώδικα σε πολύ απλή και βασική μορφή και μετά θα το τροποποιήσουμε έτσι ώστε να ακολουθεί τους σωστούς κανόνες ανάπτυξης κώδικα.

Ας γράψουμε πρώτα την κλάση που αντιπροσωπεύει το λογαριασμό που έχουμε στη τράπεζα.

Account.java

package com.bank;

public class Account {

    public float money;

    public void getBalance() {
        System.out.println("Your current balance is " + money);
    }
}

Τώρα ας δημιουργήσουμε ένα αντικείμενο είδος Account και αφού καταθέσουμε ένα χρηματικό ποσό καλώντας την money μεταβλητή, να δούμε το ποιο είναι το τελικό κατάθεσης στο λογαριασμό μας χρησιμοποιώντας την getBalance( ) μέθοδο.

Person.java

package com.bank;

public class Person {
    public static void main(String[] args) throws Exception {
        Account wallet = new Account();
        wallet.money = 500;
        wallet.getBalance();
        wallet.money = 300;
        wallet.getBalance();
    }
}

Output

Your current balance is 500.0

Your current balance is 300.0

Ας αναλύσουμε τώρα το πρόγραμμα που μόλις εκτελέσαμε και ας βρούμε τι τυχόν προβλήματα μπορεί να αντιμετωπίσουμε αν το διατηρήσουμε όπως έχει. Η κλάση Account περιέχει μια instance μεταβλητή με το όνομα money η τιμή της οποίας αντιπροσωπεύει τα λεφτά που έχουμε στον τραπεζικό μας λογαριασμό. Η μέθοδος getBalance( ) μας δείχνει, με την μορφή μηνύματος στο terminal, πόσα λεφτά υπάρχουν συνολικά στο λογαριασμό μας.

Στη κλάση Person δημιουργούμε ένα αντικείμενο είδος Account και μετά καλούμε την μεταβλητή money (μπορούμε να τη καλέσουμε άμεσα γιατί έχει οριστεί σαν public)  για να ορίσουμε το αρχικό ποσό κατάθεσης 500 ευρώ. Αμέσως μετά επιβεβαιώνουμε ότι η μεταβλητή περιέχει το ποσό καλώντας την μέθοδο getBalance( ). Μετά επιθυμούμε να αφαιρέσουμε 200 ευρώ από το λογαριασμό μας. Οπότε αναθέτουμε μια καινούργια τιμή στη μεταβλητή (300 ευρώ) η οποία αντικαταστεί την προηγούμενη τιμή.

Το απλό αυτό πρόγραμμα μπορεί στη πράξη να δουλεύει αλλά έχει πολλά κενά. Πρώτον αφήνουμε το χρήστη να κάνει κατάθεση ενός ποσού χωρίς κανένα έλεγχο στο όριο της κατάθεσης. Οπότε αν έγραφε κατά λάθος 5000 αντί για 500 το πρόγραμμα θα το δεχόταν σαν σωστή τιμή αφού προγραμματιστικά και οι δύο τιμές είναι integer. Δεύτερον, αφαιρούμε λεφτά από το τραπεζικό λογαριασμό χωρίς να κάνουμε έλεγχο αν αυτά τα λεφτά είναι διαθέσιμα. Οποιοδήποτε ποσό και να γράφαμε το πρόγραμμα μας θα το δεχόταν. Πως θα μπορούσαμε λοιπόν να αναβαθμίσουμε το κώδικα μας έτσι ώστε να προσφέρει καλύτερη ασφάλεια και σιγουριά στις συναλλαγές που εκτελούμε?

Σε αυτό λοιπόν το σημείο θα πρέπει αρχικά να αναφερθούμε στα access specifiers τα οποία έχει ορίσει η Java και είναι τα εξής:

·         public – Μας επιτρέπει να έχουμε πρόσβαση από οπουδήποτε

·         private – Πρόσβαση μόνο μέσα από την ίδια κλάση

·         protected – Πρόσβαση μόνο από το ίδιο πακέτο ή αν κληρονομούμε από τη κλάση

·         default – δεν υπάρχει λέξη κλειδί default, απλά δεν γράφουμε τίποτα σαν access specifier και αυτό μας επιτρέπει να έχουμε πρόσβαση μόνο όταν είμαστε στο ίδιο πακέτο με τη κλάση

Εμείς, μέχρι τώρα, χρησιμοποιούσαμε μόνο το public access specifier μπροστά από τις μεταβλητές και τις μεθόδους. Αυτός ο τρόπος μας έδινε πρόσβαση σε όλες τις μεταβλητές και μεθόδους του αντικειμένου. Αυτό μπορούσαμε να το επιβεβαιώσουμε όταν αμέσως μετά τον ορισμό του αντικειμένου, αν γράψουμε τελεία (object.) το IDE θα μας εμφανίσει την λίστα με τα στοιχεία της κλάσης στα οποία έχουμε πρόσβαση.

Στο πρόγραμμα μας, το να έχουμε απευθείας πρόσβαση επάνω στη μεταβλητή money χωρίς να γίνεται κάποιος έλεγχος μας δημιουργεί αρκετά προβλήματα. Ο τρόπος λοιπόν που συνήθως αντιμετωπίζουμε μια τέτοια κατάσταση είναι να αλλάζουμε το access specifier στις μεταβλητές από public σε private.

Κάνοντας αυτή την αλλαγή, και με βάση τη θεωρία που έχουμε ήδη αναφέρει, δεν θα μπορούμε από μια διαφορετική κλάση (πχ. Person) να έχουμε πρόσβαση σε αυτές τις μεταβλητές.

Ας αλλάξουμε λοιπόν το access specifier του money από public σε private. Η παρακάτω εικόνα δείχνει ότι η λίστα που εμφανίζεται, μετά τον ορισμό του αντικειμένου,  δεν περιέχει την συγκεκριμένη μεταβλητή. Οπότε δεν μπορούμε πια να την δούμε και κατά συνέπεια να τη χρησιμοποιήσουμε.

Account.java

package com.bank;

public class Account {

    private float money;

    public void getBalance() {
        System.out.println("Your current balance is " + money);
    }
}


Person.java



Με βάση τη θεωρία της Java, μπορούμε να έχουμε πρόσβαση σε private στοιχεία της κλάσης, μόνο μέσα από την ίδια κλάση δηλαδή μέσα από την κλάση Account. Εδώ λοιπόν είναι που χρειαζόμαστε την υλοποίηση των getter και setter μεθόδων. Ενώ η μεταβλητή είναι private, οι getter και setter μέθοδοι είναι public και δια μέσω αυτών μπορούμε να χειριστούμε τις τιμές των μεταβλητών.

Κάθε IDE, συμπεριλαμβανομένου και του VS Code, προσφέρουν ένα εύκολο τρόπο δημιουργίας getter και setter μεθόδων.  Κάντε δεξί κλικ μέσα σε ένα κενό σημείο της κλάσης και επιλέξτε Java Code Generators -> Generate Getters and Setters.


Η κλάση Account τώρα θα περιέχει δύο ακόμα μεθόδους.

Account.java

package com.bank;

public class Account {

    private float money;

    public void getBalance() {
        System.out.println("Your current balance is " + money);
    }

    public float getMoney() {
        return this.money;
    }

    public void setMoney(float money) {
        this.money = money;
    }
}

Η getMoney( ) απλά μας επιστρέφει την τιμή της μεταβλητής money ενώ η setMoney( ) θα περάσει μια καινούργια τιμή στην instance μεταβλητή money της κλάσης. Επίσης, επειδή και οι δύο μέθοδοι είναι public μπορούμε να έχουμε πρόσβαση σε αυτές.


ADVANTAGES OF GETTER AND SETTERS

Τι έχουμε καταφέρει με αυτή την αλλαγή? Τώρα μπορούμε να προσθέσουμε κώδικα μέσα στις μεθόδους έτσι ώστε πριν αναθέσουμε οποιαδήποτε τιμή στην μεταβλητή money να κάνουμε τους απαραίτητους ελέγχους.

 


Η παρακάτω μορφή του κώδικα είναι η τελική έκδοση του προγράμματος όπου δεν επιτρέπουμε να γίνει κατάθεση πάνω από 500 ευρώ ενώ αν δεν έχουμε αρκετά χρήματα στο λογαριασμό μας το πρόγραμμα αφού μας δείξει ένα μήνυμα στο terminal θα κάνει exit.

Account.java

package com.bank;

public class Account {

    private float money;

    public void getBalance() {
        System.out.println("Your current balance is " + money);
    }

    public void setMoney(float money) {
        if (money > 0 && money <= 500) {
            this.money = money;
        } else {
            System.out.println("Please enter a value between 0 and 500");
            System.exit(0);
        }
    }

    public void getMoney(float amount) {
        if (money >= amount) {
            money -= amount;
            System.out.println("You pull out " + amount);
            System.out.println("Your current balance is " + money);
        } else {
            System.out.println("You do not have enough money");
            System.out.println("Please deposit more money");
            System.exit(0);
        }
    }
}


Person.java

package com.bank;

public class Person {
    public static void main(String[] args) throws Exception {
        Account wallet = new Account();
        wallet.setMoney(500);
        wallet.getBalance();
        wallet.getMoney(300);
        wallet.getMoney(300);
    }
}

Output

Your current balance is 500.0

You pull out 300.0

Your current balance is 200.0

You do not have enough money

Please deposit more money

 

Πριν ολοκληρώσουμε το σημερινό δωρεάν μάθημα Java, θα ήθελα να αναφέρω ότι επίσημα η λογική του να κάνουμε private στοιχεία της κλάσης ονομάζεται encapsulation. Επίσης δεν υπάρχουν λέξεις κλειδιά getter και setter στη Java. Ακόμα και η λογική του να βάζουμε τη λέξη get ή set μπροστά από τη μέθοδο ή τη μεταβλητή είναι τίποτα άλλο από έναν άγραφο κανόνας που ακολουθούν όλοι οι Java προγραμματιστές και κατά συνέπεια το ακολουθούν και όλα τα IDE.

Μην ξεχάσετε να κάνετε ένα μικρό donation έτσι ώστε αυτό το blog να μεγαλώσει ακόμα πιο πολύ και να έχει περισσότερες δυνατότητες στην online παράδοση δωρεάν μαθημάτων.



full-width

Post a Comment

0 Comments