CodeGym /Java Blog /Random-IT /Dichiarazione di metodo
John Squirrels
Livello 41
San Francisco

Dichiarazione di metodo

Pubblicato nel gruppo Random-IT
CIAO! Hai già saputo come creare le tue classi con campi e metodi. Ora ci soffermeremo sui metodi.
Dichiarazione di metodo - 1
Naturalmente, l'abbiamo già fatto più di una volta nelle nostre lezioni, ma abbiamo trattato principalmente le generalità. Oggi analizzeremo i metodi e studieremo di cosa sono fatti, i vari modi per crearli e come gestirli. :) Andiamo!

Dichiarazione di metodo

Tutto il codice che definisce un metodo è chiamato dichiarazione di metodo . La forma generale di una dichiarazione di metodo può essere descritta come segue:

access modifier, return type, method name (parameter list) {
    // method body
}
A titolo di esempio, si dia un'occhiata alle dichiarazioni dei vari metodi della Dogclasse.

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1. Modificatore di accesso

Il modificatore di accesso è sempre indicato per primo. Tutti i Dogmetodi della classe sono contrassegnati dal modificatore public . Ciò significa che possiamo chiamarli da qualsiasi altra classe:

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
Come puoi vedere, i Dogmetodi della classe sono facilmente accessibili nella Mainclasse. Ciò è possibile grazie al modificatore public . In Java, ci sono altri modificatori. Non tutti consentono l'utilizzo di metodi in altre classi. Ne parleremo in altre lezioni. La cosa principale da ricordare è di cosa è responsabile il modificatore: se un metodo è accessibile in altre classi :)

2. parola chiave statica

Uno dei Dogmetodi, main(), è contrassegnato dalla parola chiave static . Fa anche parte della dichiarazione del metodo e ne conosciamo già il significato. Non ne abbiamo parlato nel modello di dichiarazione del metodo fornito all'inizio della lezione, perché è facoltativo. Se è specificato, deve venire dopo il modificatore di accesso. Ricordi che nelle lezioni recenti abbiamo parlato di variabili statiche (di classe)? Quando applicata ai metodi, questa parola chiave ha più o meno lo stesso significato. Se un metodo è static , può essere utilizzato senza un riferimento a un oggetto specifico della classe. E in effetti, non hai bisogno di un Dogoggetto per eseguire il main()metodo statico nel fileDogclasse. Funzionerà bene senza uno. Se questo metodo non fosse statico, avremmo prima bisogno di creare un oggetto per eseguirlo.

3. Valore di ritorno

Se il nostro metodo deve restituire qualcosa, specifichiamo il tipo del valore restituito. Questo è evidente dall'esempio del getName()getter:

public String getName() {
   return name;
}
Restituisce un Stringoggetto. Se un metodo non restituisce nulla, viene invece utilizzata la parola chiave void , come nel woof()metodo:

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

Metodi con lo stesso nome

Ci sono situazioni in cui vorremo diversi modi per chiamare un metodo. Perché non creare la nostra intelligenza artificiale? Amazon ha Alexa, Apple ha Siri, quindi perché non dovremmo averne uno? :) Nel film Iron Man, Tony Stark crea la sua incredibile intelligenza artificiale, Jarvis. Rendiamo omaggio a quel fantastico personaggio e chiamiamo la nostra IA in suo onore. :) La prima cosa che dobbiamo fare è insegnare a Jarvis a salutare le persone che entrano nella stanza (sarebbe strano se un intelletto così straordinario si rivelasse scortese).

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
Uscita console: Buonasera, Tony Stark. Come stai? Molto bene! Jarvis è ora in grado di accogliere gli ospiti. Certo, più spesso di quanto sarà il suo padrone, Tony Stark. Ma cosa succede se non viene da solo! Ma il nostro sayHi()metodo accetta solo un argomento. E quindi può salutare solo una persona che entra nella stanza e ignorerà l'altra. Non molto educato, d'accordo? :/ In questo caso, possiamo risolvere il problema semplicemente scrivendo 2 metodi con lo stesso nome, ma parametri diversi:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
Questo si chiama sovraccarico del metodo . Il sovraccarico del metodo consente al nostro programma di essere più flessibile e di adattarsi a vari modi di lavorare. Rivediamo come funziona:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Uscita console: Buonasera, Tony Stark. Come stai? Buonasera, Tony Stark e Capitan America. Come stai? Eccellente, entrambe le versioni hanno funzionato. :) Ma non abbiamo risolto il problema! E se ci sono tre ospiti? Potremmo, ovviamente, sovraccaricare sayHi()nuovamente il metodo, in modo che accetti tre nomi di ospiti. Ma potrebbero essercene 4 o 5. Fino all'infinito. Non c'è un modo migliore per insegnare a Jarvis a gestire un numero qualsiasi di nomi, senza sovraccaricare il sayHi()metodo un milione di volte()? :/ Certo che c'è! Se non ci fosse, pensi che Java sarebbe il linguaggio di programmazione più popolare al mondo? ;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Quando ( String... names ) viene utilizzato come parametro, indica che una raccolta di stringhe verrà passata al metodo. Non dobbiamo specificare in anticipo quanti saranno, quindi ora il nostro metodo è molto più flessibile:

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
Uscita console: Buonasera, Tony Stark. Come stai? Buonasera, Capitan America. Come stai? Buonasera, Vedova Nera. Come stai? Buonasera Hulk. Come stai? All'interno del metodo, iteriamo su tutti gli argomenti e mostriamo frasi formattate con nomi. Qui usiamo un for-eachciclo semplificato (che hai visto prima). È perfetto qui, perché la notazione ( String... names ) in realtà significa che il compilatore inserisce tutti gli argomenti passati in un array. Di conseguenza, possiamo lavorare con nomi di variabilicome lavoreremmo con un array, anche iterandolo in un ciclo. Inoltre, funzionerà con qualsiasi numero di stringhe passate! Due, dieci, persino mille: il metodo funzionerà correttamente con qualsiasi numero di invitati. Molto più conveniente che sovraccaricare il metodo per tutte le possibilità, non credi? :) Ecco un altro esempio di sovraccarico del metodo. Diamo un printInfoFromDatabase()metodo a Jarvis. Visualizzerà le informazioni su una persona da un database. Se il database indica che una persona è un supereroe o un supercriminale, mostreremo tali informazioni:

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
Produzione: Laura Palmer. Data di nascita: 22 luglio 1972. Twin Peaks, Washington Max Eisenhardt. Altezza: 15,6 piedi. Peso: 189 libbre. Conosciuto anche come il supercriminale Magneto Quindi, il comportamento del nostro metodo dipende dai dati che gli passiamo. Ecco un altro punto importante: l'ordine degli argomenti è importante! Diciamo che il nostro metodo accetta una stringa e un numero:

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
Se il metodo Persondella classe sayYourAge()accetta una stringa e un numero come input, allora questo è l'ordine in cui questi argomenti devono essere passati al metodo! Se li passiamo in un ordine diverso, il compilatore genererà un errore e la persona non sarà in grado di dire la sua età. A proposito, anche i costruttori, di cui abbiamo parlato nell'ultima lezione, sono metodi! Puoi anche sovraccaricarli (cioè creare diversi costruttori con diversi set di parametri) e l'ordine degli argomenti passati è di fondamentale importanza anche per loro. Sono metodi reali! :)

Come richiamare metodi con parametri simili

Come sai, nullè una parola chiave in Java. È molto importante capire che nullnon è né un oggetto né un tipo di dati . Immagina di avere una Personclasse e un introduce()metodo che annuncia il nome e l'età della persona. Inoltre, l'età può essere passata come testo o come numero.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
Abbiamo già familiarità con l'overloading, quindi sappiamo che entrambi i metodi si comporteranno come dovrebbero: My name is Alex. Ho ventuno anni, mi chiamo Mary. Ho 32 anni Ma cosa succede se passiamo nullcome secondo parametro invece di una stringa o di un numero?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
Avremo un errore di compilazione! Cosa causa questo e qual è esattamente l '"ambiguità"? In effetti, è tutto molto semplice. Il problema è che abbiamo due versioni del metodo: una con a Stringcome secondo argomento e una con an Integercome secondo argomento. Ma a Stringe an Integerpossono essere entrambi null! Poiché sono tipi di riferimento, nullè il valore predefinito per entrambi. Ecco perché in questa situazione il compilatore non riesce a capire quale versione del metodo dovrebbe chiamare. La soluzione a questo problema è abbastanza semplice. Nullpuò essere convertito in modo esplicito in un tipo di riferimento specifico. Pertanto, quando chiami un metodo, puoi indicare tra parentesi il tipo di dati che desideri per il secondo argomento! Il compilatore capirà il tuo "suggerimento" e chiamerà il metodo corretto:

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
Output: Metodo con due stringhe! Mi chiamo Vittorio. La mia età è null Si noti che se il parametro number fosse un primitive int, piuttosto che un'istanza del tipo di riferimento Integer, non ci sarebbe stato un tale errore.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
Riesci a indovinare perché? Se hai indovinato perché, ben fatto! :) Perché le primitive non possono essere null. Ora il compilatore ha una sola scelta, ovvero chiamare il introduce()metodo con due stringhe. Questa è la versione del metodo che verrà eseguita ogni volta che viene chiamato il metodo.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION