Στο σημερινό δωρεάν μάθημα Java θα μιλήσουμε για το τι σημαίνει να δημιουργήσουμε overload μεθόδους. Αυτή η θεωρία θα μας φανεί πολύ χρήσιμη πολύ σύντομα όταν θα μιλήσουμε περισσότερο και πιο αναλυτικά για τους constructors.
Τι είναι λοιπόν το overloading? Είναι η δυνατότητα που μας δίνει η java να έχουμε πολλαπλές μεθόδους με το ίδιο όνομα μέσα στην ίδια κλάση. Η java μας επιτρέπει να υπάρχει πολλαπλές φορές το ίδιο όνομα μεθόδου μέσα στην ίδια κλάση αρκεί το signature της μεθόδου να διαφέρει. Υπενθυμίζω ότι σαν signature είχαμε ορίσει την γραμμή εκείνη που ορίζει το όνομα της μεθόδου, τις παραμέτρους της, το return type και τον access specifier. Η java λοιπόν, για να μπορέσει να ξεχωρίσει τις μεθόδους μεταξύ τους, διαβάζει το signature της κάθε μεθόδου. Πιο συγκεκριμένα την ενδιαφέρει ο αριθμός και τα data types των παραμέτρων που περνάμε στην μέθοδο παρά το return type. Βασικά το return type από μόνο του δεν είναι ικανό να μας προσφέρει το overloading.
Ας δούμε ένα παράδειγμα στο οποίο προσπαθούμε να δημιουργήσουμε ένα είδος μεθόδου που θα μπορεί να πολλαπλασιάζει όλα τα είδη των αριθμών - πχ. δύο int αριθμούς ή έναν int και ένα float. Δημιουργούμε ένα καινούργιο project με το όνομα CalculatorDemo μέσα στο οποίο θα φτιάξουμε το πακέτο com.overload. Ο κώδικας που ακολουθεί είναι μια κλάση με το όνομα Calculator η οποία περιέχει τις overloaded μεθόδους και η κλάση OverloadDemo από την οποία δημιουργούμε ένα αντικείμενο είδος Calculator και καλούμε τις μεθόδους του.
Calculator.java
package com.overload; public class Calculator { public int multiply(int x, int y) { System.out.println("Multiply int * int"); return x * y; } public double multiply(double x, double y) { System.out.println("Multiply double * double"); return x * y; } public double multiply(int x, double y) { System.out.println("Multiply int * double"); return x * y; } public int multiply(int x) { System.out.println("Multiply int * itself"); return x * x; } public int multiply(int x, int y, int z) { System.out.println("Multiply three ints"); return x * y * z; } }
OverloadDemo.java
package com.overload; public class OverloadDemo { public static void main(String [] args) { System.out.println("Instantiating a Calculator..."); Calculator calc = new Calculator(); System.out.println("Initializing some variables..."); int a = 5; int b = 8; double d1 = 2.5; double d2 = -1.0; float f = 4.0F; int intAnswer = 0; double doubleAnswer = 0.0; intAnswer = calc.multiply(a, b); System.out.println(a + " * " + b + " = " + intAnswer); doubleAnswer = calc.multiply(d1, d2); System.out.println(d1 + " * " + d2 + " = " + doubleAnswer); intAnswer = calc.multiply(b); System.out.println(b + " * " + b + " = " + intAnswer); intAnswer = calc.multiply(a, b, a); System.out.println(a + " * " + b + " * " + a + " = " + intAnswer); doubleAnswer = calc.multiply(b, f); System.out.println(b + " * " + f + " = " + doubleAnswer); doubleAnswer = calc.multiply(d2, f); System.out.println(d2 + " * " + f + " = " + doubleAnswer); } }
Output
Instantiating a Calculator... Initializing some variables... Multiply int * int 5 * 8 = 40 Multiply double * double 2.5 * -1.0 = -2.5 Multiply int * itself 8 * 8 = 64 Multiply three ints 5 * 8 * 5 = 200 Multiply int * double 8 * 4.0 = 32.0 Multiply double * double -1.0 * 4.0 = -4.0
Ας δούμε πως ακριβώς πραγματοποιήσαμε το overloading στην κλάση Calculator. Θα συγκρίνουμε τις δύο πρώτες μεθόδους γιατί και οι υπόλοιπες ακολουθούν την ίδια λογική.
Έχουμε λοιπόν μια μέθοδο με το όνομα mutliply η οποία δέχεται δυο int τιμές και επιστρέφει int τιμή. Η Java ενδιαφέρεται κυρίως για το είδος των τιμών που περνάμε στην μέθοδο. Στην δεύτερη μέθοδο περνάνε δύο double τιμές. Επειδή το signature της μια μεθόδου διαφέρει από εκείνο της δεύτερης η java επιτρέπει το overloading. Καταλαβαίνετε λοιπόν ότι οποιοσδήποτε μοναδικός συνδυασμός ανάμεσα στις μεταβλητές θα μας επιτρέπει να πραγματοποιήσουμε overloading. Και αυτή είναι η λογική που ακολουθούμε στις υπόλοιπες μεθόδους – int και double, μια int, τρεις int κτλ.
Τώρα αν νομίζετε ότι μια τέτοια προσέγγιση ίσως να μην σας είναι χρήσιμη, σας προτείνω να το σκεφτείτε πάλι επειδή η ίδια η java λειτουργεί κάτω από την έννοια του overloading. Ο εύκολος τρόπος να το αποδείξουμε αυτό είναι αν τυπώσετε System.out. Εκεί θα δείτε μια λίστα από println και print μεθόδους. Εσείς δεν επιλέγετε ποια από αυτές τις μεθόδους θα εκτελεστούν. Αυτό το κάνει η java ανάλογα με το input που παρέχετε στις μεθόδους.
Στην κλάση OverloadDemo, σαν πρώτο βήμα, δημιουργούμε ένα αντικείμενο από την κλάση Calculator και ορίζουμε μερικές τοπικές μεταβλητές διαφορετικών τύπων και τιμών. Αμέσως μετά φαίνεται η πραγματική αξία του overloading που πραγματοποιήσαμε. Όπως η java επιλέγει για εμάς ποια println ή print μέθοδο θα εκτελέσει, έτσι και το δικό μας πρόγραμμα επιλέγει ποια μέθοδο θα εκτελέσει ανάλογα με το είδος των τιμών που θα περάσουμε στην μέθοδο. Η ουσία στην όλη διαδικασία είναι ότι εμείς σαν προγραμματιστές έχουμε να καλέσουμε ένα όνομα (multiply) και απλά να περάσουμε τις τιμές.
Την πρώτη φορά καλούμε την multiply μέθοδο περνώντας δύο int τιμές. Η java ανατρέχει πίσω στην κλάση Calculator από την οποία δημιουργήσαμε το αντικείμενο και εξετάζει αν υπάρχει κάποια μέθοδο που να δέχεται δύο int τιμές. Αν ναι τότε την εκτελεί, αν όχι θα μας επιστρέψει λάθος. Αν και είναι λίγο δύσκολο να κάνουμε λάθος στο input που δίνουμε στις μεθόδους αφού όταν γράφουμε το αντικείμενο, η λίστα των μεθόδων που εμφανίζεται περιλαμβάνει και το επιθυμητό input των μεθόδων.