CodeGym /Blog Java /Aleatoriu /Declarație de metodă
John Squirrels
Nivel
San Francisco

Declarație de metodă

Publicat în grup
Bună! Știați deja despre crearea propriilor clase cu câmpuri și metode. Acum ne vom opri asupra metodelor.
Declarație de metodă - 1
Desigur, am făcut deja acest lucru de mai multe ori în lecțiile noastre, dar am abordat în principal generalități. Astăzi, vom analiza metodele și vom studia din ce sunt făcute, diferitele modalități de a le crea și cum să le gestionăm pe toate. :) Să mergem!

Declarație de metodă

Tot codul care definește o metodă se numește declarație de metodă . Forma generală a unei declarații de metodă poate fi descrisă după cum urmează:

access modifier, return type, method name (parameter list) {
    // method body
}
Ca exemple, aruncați o privire la declarațiile diferitelor metode ale Dogclasei.

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. Modificator de acces

Modificatorul de acces este întotdeauna indicat primul. Toate Dogmetodele clasei sunt marcate cu modificatorul public . Aceasta înseamnă că le putem numi din orice altă clasă:

public class Main {

   public static void main(String[] args) {

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

}
După cum puteți vedea, Dogmetodele clasei sunt ușor de accesat în Mainclasă. Acest lucru este posibil datorită modificatorului public . În Java, există alți modificatori. Nu toate permit utilizarea metodelor în alte clase. Vom vorbi despre ele în alte lecții. Principalul lucru de reținut este de ce este responsabil modificatorul: dacă o metodă este accesibilă în alte clase :)

2. cuvânt cheie static

Una dintre Dogmetode, main(), este marcată cu cuvântul cheie static . De asemenea, face parte din declarația metodei și îi știm deja semnificația. Nu am menționat-o în șablonul de declarație de metodă dat la începutul lecției, deoarece este opțional. Dacă este specificat, atunci trebuie să vină după modificatorul de acces. Vă amintiți că în lecțiile recente am vorbit despre variabile statice (de clasă)? Când este aplicat metodelor, acest cuvânt cheie are aproximativ același sens. Dacă o metodă este statică , atunci poate fi folosită fără referire la un obiect specific al clasei. Și într-adevăr, nu aveți nevoie de un Dogobiect pentru a rula metoda statică main()înDogclasă. Va merge bine fără unul. Dacă această metodă nu ar fi statică, atunci ar trebui mai întâi să creăm un obiect pentru a-l rula.

3. Valoarea returnată

Dacă metoda noastră ar trebui să returneze ceva, atunci specificăm tipul valorii returnate. Acest lucru este evident din exemplul getterului getName():

public String getName() {
   return name;
}
Returnează un Stringobiect. Dacă o metodă nu returnează nimic, atunci se folosește cuvântul cheie voidwoof() , ca în metoda:

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

Metode cu același nume

Există situații în care vom dori mai multe moduri diferite de a apela o metodă. De ce să nu ne creăm propria noastră inteligență artificială? Amazon are Alexa, Apple are Siri, așa că de ce nu ar trebui să avem unul? :) În filmul Iron Man, Tony Stark își creează propria sa incredibilă inteligență artificială, Jarvis. Să aducem un omagiu acelui personaj minunat și să numim AI-ul nostru în onoarea lui. :) Primul lucru pe care trebuie să-l facem este să-l învățăm pe Jarvis să salută oamenii care intră în cameră (ar fi ciudat dacă un intelect atât de uimitor s-ar dovedi nepoliticos).

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");
   }
}
Ieșire din consolă: Bună seara, Tony Stark. Ce mai faci? Foarte bun! Jarvis este acum capabil să primească oaspeții. Desigur, mai des decât va fi maestrul lui, Tony Stark. Dar dacă nu vine singur! Dar sayHi()metoda noastră acceptă doar un singur argument. Și astfel poate saluta doar o persoană care intră în cameră și o va ignora pe cealaltă. Nu foarte politicos, de acord? :/ În acest caz, putem rezolva problema prin simpla scriere a 2 metode cu același nume, dar cu parametri diferiți:

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?");
   }

}
Aceasta se numește supraîncărcare a metodei . Supraîncărcarea metodelor permite programului nostru să fie mai flexibil și să se adapteze la diferite moduri de lucru. Să analizăm cum funcționează:

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");
   }
}
Ieșire din consolă: Bună seara, Tony Stark. Ce mai faci? Bună seara, Tony Stark și Căpitanul America. Ce mai faci? Excelent, ambele versiuni au funcționat. :) Dar nu am rezolvat problema! Dacă sunt trei oaspeți? Am putea, desigur, să supraîncărcăm sayHi()metoda din nou, astfel încât să accepte trei nume de invitați. Dar ar putea fi 4 sau 5. Până la infinit. Nu există o modalitate mai bună de a-l învăța pe Jarvis să gestioneze orice număr de nume, fără a supraîncărca sayHi()metoda de un milion de ori()? :/ Sigur că există! Dacă nu ar exista, crezi că Java ar fi cel mai popular limbaj de programare din lume? ;)

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");
   }
}
Când ( String... names ) este folosit ca parametru, indică faptul că o colecție de șiruri va fi transmisă metodei. Nu trebuie să precizăm în prealabil câți vor fi, așa că acum metoda noastră este mult mai flexibilă:

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");
   }
}
Ieșire din consolă: Bună seara, Tony Stark. Ce mai faci? Bună seara, căpitane America. Ce mai faci? Bună seara, văduva neagră. Ce mai faci? Bună seara, Hulk. Ce mai faci? În cadrul metodei, iterăm peste toate argumentele și afișăm fraze formatate cu nume. Aici folosim o for-eachbuclă simplificată (pe care ați văzut-o înainte). Este perfect aici, deoarece notația ( String... names ) înseamnă de fapt că compilatorul pune toate argumentele transmise într-o matrice. Ca rezultat, putem lucra cu nume de variabileașa cum am lucra cu o matrice, inclusiv prin iterarea printr-o buclă. În plus, va funcționa cu orice număr de șiruri trecute! Doi, zece, chiar o mie — metoda va funcționa corect cu orice număr de oaspeți. Mult mai convenabil decât supraîncărcarea metodei pentru toate posibilitățile, nu crezi? :) Iată un alt exemplu de supraîncărcare a metodei. Să-i dăm lui Jarvis o printInfoFromDatabase()metodă. Acesta va afișa informații despre o persoană dintr-o bază de date. Dacă baza de date indică faptul că o persoană este un super-erou sau un supercriminal, vom afișa aceste informații:

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");
   }
}
Ieșire: Laura Palmer. Data nașterii: 22 iulie 1972. Twin Peaks, Washington Max Eisenhardt. Înălțime: 15,6 ft. Greutate: 189 lbs. Cunoscut și sub numele de supercriminal Magneto Deci, comportamentul metodei noastre depinde de datele pe care i le transmitem. Iată un alt punct important: ordinea argumentelor contează! Să presupunem că metoda noastră ia un șir și un număr:

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!
   }
}
Dacă metoda Personclasei sayYourAge()ia ca intrare un șir și un număr, atunci aceasta este ordinea în care aceste argumente trebuie să fie transmise metodei! Dacă le trecem într-o ordine diferită, atunci compilatorul va genera o eroare și persoana nu va putea să-și spună vârsta. Apropo, constructorii, pe care i-am abordat în ultima lecție, sunt și metode! De asemenea, le puteți supraîncărca (adică creați mai mulți constructori cu seturi diferite de parametri), iar ordinea argumentelor transmise este fundamental și pentru ei. Sunt metode reale! :)

Cum se invocă metode cu parametri similari

După cum știți, nulleste un cuvânt cheie în Java. Este foarte important să înțelegeți că nullnu este nici un obiect, nici un tip de date . Imaginează-ți că avem o Personclasă și o introduce()metodă, care anunță numele și vârsta persoanei. În plus, vârsta poate fi transmisă ca text sau ca număr.

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);
   }
}
Suntem deja familiarizați cu supraîncărcarea, așa că știm că ambele metode se vor comporta așa cum ar trebui: Numele meu este Alex. Vârsta mea este de douăzeci și unu Numele meu este Mary. Vârsta mea este 32. Dar ce se va întâmpla dacă trecem nullca al doilea parametru în loc de șir sau număr?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
Vom primi o eroare de compilare! Ce cauzează acest lucru și care este exact „ambiguitatea”? De fapt, totul este foarte simplu. Problema este că avem două versiuni ale metodei: una cu a Stringca al doilea argument și alta cu an Integerca al doilea argument. Dar a Stringși an Integerpot fi ambele null! Deoarece sunt tipuri de referință, nulleste valoarea implicită pentru ambele. De aceea, în această situație, compilatorul nu își poate da seama ce versiune a metodei ar trebui să apeleze. Soluția la această problemă este destul de simplă. Nullpoate fi convertit în mod explicit într-un tip de referință specific. Astfel, atunci când apelați o metodă, puteți indica între paranteze tipul de date dorit pentru al doilea argument! Compilatorul vă va înțelege „hint” și va apela metoda corectă:

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);
   }
}
Ieșire: Metodă cu două șiruri! Numele meu este Victor. Vârsta mea este nulă. Rețineți că dacă parametrul număr ar fi fost un primitiv int, mai degrabă decât o instanță a tipului de referință Integer, nu ar fi existat o astfel de eroare.

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);
   }
}
Poți ghici de ce? Dacă ai ghicit de ce, bravo! :) Pentru că primitivii nu pot fi null. Acum compilatorul are o singură alegere, adică să apeleze introduce()metoda cu două șiruri. Aceasta este versiunea metodei care va rula de fiecare dată când metoda este apelată.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION