JAVA ENOTHTA 14 – METHODS

 


ΕΙΣΑΓΩΓΗ

Στο σημερινό δωρεάν μάθημα Java θα αναφερθούμε στις μεθόδους (methods) και πιο συγκεκριμένα θα δούμε πως συντάσσονται, 

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

METHOD STRUCTURE

Όπως ήδη έχουμε αναφέρει στην προηγούμενη δωρεάν ενότητα Java, οι μέθοδοι εκφράζουν την συμπεριφορά του αντικειμένου – δηλαδή το τι μπορούμε να κάνουμε με το αντικείμενο.

Μπορούμε όμως και να δημιουργήσουμε μεθόδους που δεν ανήκουν σε κάποιο αντικείμενο αλλά ανήκουν στην κλάση και απλά τις καλούμε αυτόνομα. Αυτή είναι η static ιδιότητα και σε αυτή την κατηγορία ανήκει και η main( ) μέθοδο που ήδη χρησιμοποιείται στα προγράμματα σας. Άλλωστε μπορούμε να ξεχωρίσουμε αυτή την ιδιότητα της main( ) γιατί πριν από το όνομα της υπάρχει η λέξη static. Ο compiler της Java δεν χρειάζεται να δημιουργήσει αντικείμενο από την κλάση που ανήκει η main( ) αφού είναι static. Απλά την καλεί απευθείας και ο κώδικα μας εκτελείται. Θα μιλήσουμε σε μελλοντική ενότητα πιο συγκεκριμένα για το πώς ακριβώς δουλεύει η έννοια του static.

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

Η γενική δομή της μεθόδου είναι η εξής:

modifiers return-type method-name (parameters-list) [throws-clause] {

// Body of the method goes here

}

CALLING A METHOD

Πριν όμως πούμε περισσότερα για την θεωρία, ας προσθέσουμε μερικές ακόμα μεταβλητές στον κώδικα της κλάσης Employee που είχαμε δημιουργήσει στην προηγούμενη ενότητα. Βασικά θα αντικαταστήσουμε την μεταβλητή salary με δύο μεταβλητές: netIncome και grossSalary και θα προσθέσουμε μια επιπλέον μεταβλητή που θα αντιπροσωπεύει τα εξαρτώμενα μέλη (dependents). Επίσης θα εισάγουμε και UML αντιπροσώπευση των κλάσεων για να έχετε μια πιο οπτική εικόνα των συνδέσεων και εξαρτήσεων ανάμεσα τους. Ο κώδικας μας είναι τώρα ο εξής:

Employee.java

package com.example;

public class Employee {
    public String name;
    public int AFM;
    public int employeeId;
    public double grossIncome;
    public double netIncome;
    public String department;
    public int dependents;
}

Ας προσθέσουμε τώρα στην κλάση Employee την πρώτη μέθοδο με το όνομα mailCheck. Κάθε μέθοδο πρέπει να έχει ένα όνομα και να ακολουθείται από παρένθεση. Η ονομασία της μεθόδου είναι mailCheck( ) και ακολουθεί τους ίδιους γενικούς κανόνες όπως εκείνων των μεταβλητών. Αμέσως πριν από το όνομα πρέπει να δηλώσουμε το data type της τιμής που θα μας επιστρέφει η μέθοδος. Η mailCheck( ) δεν επιστρέφει τίποτα πίσω στο πρόγραμμα απλά τυπώνει στο terminal ένα μήνυμα στην οθόνη. Για να δηλώσουμε ότι δεν περιμένουμε από την μέθοδο να μας επιστρέψει κάποια τιμή πίσω στο πρόγραμμα χρησιμοποιούμε την λέξη κλειδί void. Για να μπορούμε να έχουμε πρόσβαση στην μέθοδο από οποιαδήποτε άλλη κλάση, δηλώνουμε την πρόσβαση σαν public. Τα άλλα είδη access specifiers (ή modifiers) είναι private, protected και default access. Ακριβώς τα ίδια όπως και στις μεταβλητές. Με τα access specifiers ή modifiers θα ασχοληθούμε εκτενέστερα σε μελλοντική ενότητα. Για τώρα χρησιμοποιούμε public και στις instance μεταβλητές και στις μεθόδους έτσι ώστε όταν δημιουργήσουμε το αντικείμενο μας να έχουμε πρόσβαση σε όλες τις μεταβλητές και μεθόδους του αντικειμένου. Τέλος, αν η μέθοδος περιέχει έναν πιο πολύπλοκο κώδικα (π.χ άνοιγμα και διάβασμα αρχείου) υπάρχει περίπτωση να μην εκτελεστεί σωστά και να μας επιστρέψει λάθος, αν για παράδειγμα, λείπει το αρχείο. Σε αυτή την περίπτωση θα πρέπει ο κώδικας μας να περιέχει λογική διαχείρισης λαθών ή όπως αλλιώς ονομάζονται try-catch. Δεν χρειάζεται να μπούμε σε αυτή την κατηγορία της θεωρίας ακόμα. Αυτό όμως που πρέπει να προσθέσουμε είναι ότι ολόκληρος ο κώδικας οποιασδήποτε μεθόδου περιέχεται μέσα σε άγκιστρα ( { } ).

 Ας δούμε τώρα πως έχει αλλάξει ό κώδικας της κλάσης Employee μετά την προσθήκη της μεθόδου mailCheck().

Employee.java

package com.example;

public class Employee {
    public String name;
    public int AFM;
    public int employeeId;
    public double grossIncome;
    public double netIncome;
    public String department;
    public int dependents;

    public void mailCheck() {
        System.out.println("Mailing a check to " + name);
    }
}


EmployeeDemo.java

package com.example;

public class EmployeeDemo {
    public static void main(String[] args) {
        Employee michail = new Employee();
        michail.name = "Michail Kassapoglou";
        michail.mailCheck();
    }
}

Output

Mailing a check to Michail Kassapoglou


UML


Η δεύτερη μέθοδο calcCheck( ) που θα προσθέσουμε στην κλάση Employee ακολουθεί την ίδια δομή με την πρώτη μέθοδο με την διαφορά ότι αντί για void θα μας επιστρέψει μια double τιμή πίσω στο πρόγραμμα η οποία θα είναι ο υπολογισμός του φόρου ανάλογα με το εισόδημα του εργαζόμενου. Επίσης επειδή η μέθοδος θα μας επιστρέψει τιμή είναι απαραίτητη η χρήση της λέξης κλειδί return. Εδώ κάνουμε return την τιμή που περιέχει η τοπική μεταβλητή taxes.

Όταν αναφέρουμε ότι μια μέθοδο κάνει return δεν εννοούμε ότι κάνει return στο terminal (όπως η println( ) ) αλλά ότι επιστρέφει μια τιμή πίσω στο κύριο κώδικα. Οπότε στην γραμμή 

michail.countryTaxes=michail.calcTax();

αναθέτουμε την τιμή που επιστρέφει η calcTax() στη μεταβλητή countryTaxes.

Ας δούμε πως έχουμε τροποποιήσει την Employee και την EmployeeDemo.

Employee.java

package com.example;

public class Employee {
    public String name;
    public int AFM;
    public int employeeId;
    public double grossIncome;
    public double netIncome;
    public String department;
    public int dependents;
    public double countryTaxes;

    public void mailCheck() {
        System.out.println("Mailing a tax report to " + name);
        System.out.println("Your final income after taxes is: " + netIncome);
    }

    public double calcTax() {
        double taxes = 0;
        if (grossIncome < 30000) {
            taxes = grossIncome * 0.05;
        } else {
            taxes = grossIncome * 0.06;
        }

        return taxes;
    }
}


EmployeeDemo.java

package com.example;

public class EmployeeDemo {
    public static void main(String[] args) {
        Employee michail = new Employee();
        michail.name = "Michail Kassapoglou";
        michail.grossIncome = 28000;
        michail.countryTaxes = michail.calcTax();
        michail.netIncome = michail.grossIncome - michail.countryTaxes;
        michail.mailCheck();
    }
}

Output

Mailing a tax report to Michail Kassapoglou

Your final income after taxes is: 26600.0

 

UML


Η τρίτη και τελευταία μέθοδος vacationCalc( ) χρησιμοποιεί όλα όσα έχουμε αναφέρει μέχρι τώρα. Επιστρέφει έναν int αριθμό δια μέσω της μεταβλητής remainingDays όταν εκτελεστεί. Επιπλέον δέχεται και δύο μεταβλητές – την daysTotal και την daysRequested. Αυτές οι μεταβλητές είναι local μεταβλητές τις μεθόδου που σημαίνει ότι υπάρχουν αποκλειστικά και μόνο μέσα στην μέθοδο vacationCalc( ). Οι δύο αυτές παράμετροι ορίζονται η κάθε μια ξεχωριστά με το δικό της data type. Όταν καλέσουμε την μέθοδο θα πρέπει να δώσουμε τιμές σε αυτές τις δύο παραμέτρους ειδάλλως δεν θα εκτελεστεί το πρόγραμμα μας.

 Σε κάθε μέθοδο η πρώτη γραμμή κώδικα που την δηλώνει και περιλαμβάνει το access modifier, το return type, το όνομα και της παραμέτρους ονομάζεται method signature

Αυτή είναι μια πληροφορία που αργότερα θα μας φανεί πολύ χρήσιμη όταν μιλήσουμε για method overloading.

Ας δούμε πως αλλάζει τώρα ο κώδικας των δύων κλάσεων και ποιο είναι το αποτέλεσμα της εκτέλεσης.

Employee.java

package com.example;

public class Employee {
    public String name;
    public int AFM;
    public int employeeId;
    public double grossIncome;
    public double netIncome;
    public String department;
    public int dependents;
    public double countryTaxes;

    public void mailCheck() {
        System.out.println("Mailing a tax report to " + name);
        System.out.println("Your final income after taxes is: " + netIncome);
    }

    public double calcTax() {
        double taxes = 0;
        if (grossIncome < 30000) {
            taxes = grossIncome * 0.05;
        } else {
            taxes = grossIncome * 0.06;
        }

        return taxes;
    }

    public int vacationCalc(int daysTotal, int daysRequested) {
        int remainingDays = daysTotal - daysRequested;
        System.out.println("You have requested " + daysRequested + " days of vacation");
        return remainingDays;
    }
}


EmployeeDemo.java

package com.example;

public class EmployeeDemo {
    public static void main(String[] args) {
        Employee michail = new Employee();
        michail.name = "Michail Kassapoglou";
        michail.grossIncome = 28000;
        michail.countryTaxes = michail.calcTax();
        michail.netIncome = michail.grossIncome - michail.countryTaxes;
        michail.mailCheck();

        int vacation = michail.vacationCalc(22, 5);
        System.out.println("You still have " + vacation + " of vacation days left");
    }
}


Output

Mailing a tax report to Michail Kassapoglou

Your final income after taxes is: 26600.0

You have requested 5 days of vacation

You still have 17 of vacation days left


UML


Δημιουργήσαμε ένα instance (αντικείμενο) από την κλάση Employee και ορίσαμε ένα reference (michail) για να έχουμε πρόσβαση στις μεταβλητές και μεθόδους του αντικειμένου. Σας υπενθυμίζω ότι δύο είναι οι λόγοι που μας επιτρέπουν να βλέπουμε και τις μεθόδους και τις μεταβλητές: Πρώτον γιατί και οι δύο κλάσεις είναι στο ίδιο πακέτο, και δεύτερον το access modifier είναι public. Αργότερα θα δούμε πως η αλλαγή του access specifier μπορεί να επηρεάσει την πρόσβαση μας στα χαρακτηριστικά και τις ιδιότητες του αντικειμένου.

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


full-width

Post a Comment

0 Comments