CodeGym /Java blog /Véletlen /Módszer nyilatkozat
John Squirrels
Szint
San Francisco

Módszer nyilatkozat

Megjelent a csoportban
Szia! Ön már tudta, hogyan hozhat létre saját osztályokat mezőkkel és metódusokkal. Most a módszereken fogunk foglalkozni.
Módszer nyilatkozat - 1
Természetesen ezt már többször megtettük óráinkon, de elsősorban általánosságokkal foglalkoztunk. Ma módszereket fogunk boncolgatni, és azt tanulmányozzuk, hogy miből készülnek, hogyan lehet létrehozni őket, és hogyan kezeljük mindezt. :) Gyerünk!

Módszer nyilatkozat

A metódusokat meghatározó összes kódot metódusdeklarációnak nevezzük . A metódus deklaráció általános formája a következőképpen írható le:

access modifier, return type, method name (parameter list) {
    // method body
}
Példaként tekintse meg az Dogosztály különféle metódusainak deklarációit.

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. Hozzáférés módosító

Először mindig a hozzáférés módosító jelenik meg. DogAz osztály összes metódusa nyilvános módosítóval van megjelölve. Ez azt jelenti, hogy bármelyik másik osztályból hívhatjuk őket:

public class Main {

   public static void main(String[] args) {

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

}
Mint látható, az Dogosztály metódusai könnyen elérhetők az osztályban Main. Ez a nyilvános módosító miatt lehetséges . A Java-ban vannak más módosítók is. Nem mindegyik engedélyezi a metódusok használatát más osztályokban. Más leckéken fogunk beszélni róluk. A legfontosabb dolog, amit meg kell jegyezni , hogy a módosító miért felelős: hogy egy metódus elérhető-e más osztályokban :)

2. statikus kulcsszó

Az egyik Dogmetódus, a staticmain() kulcsszóval van jelölve . Ez is része a metódus deklarációjának, és már ismerjük a jelentését. A lecke elején megadott metódus deklarációs sablonban nem említettük, mert nem kötelező. Ha meg van adva, akkor a hozzáférés módosító után kell jönnie. Emlékszel, hogy a legutóbbi órákon statikus (osztály) változókról beszéltünk? Metódusokra alkalmazva ennek a kulcsszónak nagyjából ugyanaz a jelentése. Ha egy metódus statikus , akkor az osztály egy adott objektumára való hivatkozás nélkül is használható. És valóban, nincs szükség objektumra a statikus metódus futtatásához aDogmain()Dogosztály. Egyik nélkül is jól megy. Ha ez a módszer nem statikus, akkor először létre kell hoznunk egy objektumot a futtatáshoz.

3. Visszatérési érték

Ha a metódusunknak vissza kell adnia valamit, akkor megadjuk a visszatérési érték típusát. Ez nyilvánvaló a getter példájából getName():

public String getName() {
   return name;
}
Egy objektumot ad vissza String. Ha egy metódus nem ad vissza semmit, akkor helyette a void kulcsszó kerül felhasználásra, mint a metódusban woof():

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

Azonos nevű módszerek

Vannak olyan helyzetek, amikor többféleképpen is meg akarunk hívni egy metódust. Miért ne hoznánk létre saját mesterséges intelligenciánkat? Az Amazonnak Alexa, az Apple-nek Sirije van, miért ne lehetne nekünk is? :) A Vasember című filmben Tony Stark megalkotja saját hihetetlen mesterséges intelligenciáját, Jarvist. Adjunk tiszteletet ennek a fantasztikus karakternek, és nevezzük el a mesterséges intelligenciánkat az ő tiszteletére. :) Az első dolgunk, hogy megtanítsuk Jarvist köszönni azoknak, akik belépnek a szobába (furcsa lenne, ha egy ilyen csodálatos intellektus udvariatlannak bizonyulna).

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");
   }
}
Konzol kimenet: Jó estét, Tony Stark. Hogy vagy? Nagyon jó! Jarvis mostantól vendégeket fogadhat. Természetesen gyakrabban, mint a gazdája, Tony Stark. De mi van, ha nem egyedül jön! De a mi sayHi()módszerünk csak egy érvet fogad el. Így csak egy személyt üdvözölhet, aki belép a szobába, és figyelmen kívül hagyja a másikat. Nem túl udvarias, egyetértesz? :/ Ebben az esetben úgy tudjuk megoldani a problémát, hogy egyszerűen írunk 2 azonos nevű, de eltérő paraméterű metódust:

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

}
Ezt módszer túlterhelésnek nevezik . A módszer túlterhelése lehetővé teszi, hogy programunk rugalmasabb legyen, és alkalmazkodjon a különféle munkamódszerekhez. Tekintsük át, hogyan működik:

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");
   }
}
Konzol kimenet: Jó estét, Tony Stark. Hogy vagy? Jó estét, Tony Stark és Amerika Kapitány. Hogy vagy? Kiváló, mindkét verzió működött. :) De nem oldottuk meg a problémát! Mi van, ha három vendég lesz? Természetesen ismét túlterhelhetjük a sayHi()metódust, hogy három vendégnevet fogadjon el. De lehet 4 vagy 5. Egészen a végtelenségig. Nincs jobb módja annak, hogy megtanítsuk Jarvist tetszőleges számú név kezelésére anélkül, hogy sayHi()milliószor() túlterhelnénk a metódust? :/ Persze hogy van! Ha nem lenne, szerinted a Java lenne a legnépszerűbb programozási nyelv a világon? ;)

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");
   }
}
Ha a ( String... names ) paramétert használjuk, az azt jelzi, hogy a String gyűjtemény átadásra kerül a metódusnak. Nem kell előre megadnunk, hogy hányan lesznek, így most sokkal rugalmasabb a módszerünk:

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");
   }
}
Konzol kimenet: Jó estét, Tony Stark. Hogy vagy? Jó estét, Amerika kapitány. Hogy vagy? Jó estét, Fekete Özvegy! Hogy vagy? Jó estét, Hulk. Hogy vagy? A metóduson belül az összes argumentumot iteráljuk, és nevekkel formázott kifejezéseket jelenítünk meg. Itt egy egyszerűsített hurkot használunk for-each(amit korábban láttál). Itt tökéletes, mert a ( String... names ) jelölés valójában azt jelenti, hogy a fordító az összes átadott argumentumot egy tömbbe helyezi. Ennek eredményeként dolgozhatunk változónevekkelahogyan egy tömbbel dolgoznánk, beleértve a ciklusban való iterációt is. Ráadásul tetszőleges számú átadott karakterlánccal működik! Kettő, tíz, akár ezer – a módszer tetszőleges számú vendég esetén megfelelően működik. Sokkal kényelmesebb, mint túlterhelni a módszert az összes lehetőséghez, nem gondolod? :) Itt van egy másik példa a módszer túlterhelésére. Adjunk egy printInfoFromDatabase()módszert Jarvisnek. Információkat jelenít meg egy személyről egy adatbázisból. Ha az adatbázis azt jelzi, hogy egy személy szuperhős vagy szupergonosz, akkor ezt az információt megjelenítjük:

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");
   }
}
Kimenet: Laura Palmer. Születési idő: 1972. július 22. Twin Peaks, Washington Max Eisenhardt. Magasság: 15,6 láb Súly: 189 font. Más néven Magneto szupergonosz Tehát módszerünk viselkedése attól függ, hogy milyen adatokat továbbítunk neki. Itt van még egy fontos szempont: az érvek sorrendje számít! Tegyük fel, hogy a módszerünk egy karakterláncot és egy számot vesz fel:

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!
   }
}
Ha az Personosztály sayYourAge()metódusa egy karakterláncot és egy számot vesz be bemenetként, akkor ezeket az argumentumokat ebben a sorrendben kell átadni a metódusnak! Ha más sorrendben adjuk át őket, akkor a fordító hibát generál, és a személy nem tudja megmondani az életkorát. Egyébként a konstruktorok is, amelyekről az előző leckében foglalkoztunk, szintén módszerek! Ezeket túlterhelhetjük is (pl. több konstruktort hozhatunk létre különböző paraméterkészletekkel), és az átadott argumentumok sorrendje is alapvetően fontos számukra. Ezek igazi módszerek! :)

Hogyan hívjunk meg hasonló paraméterekkel rendelkező metódusokat

Mint tudod, nullez egy kulcsszó a Java nyelven. Nagyon fontos megérteni, hogy ez nullsem nem objektum, sem nem adattípus . Képzeljük el, hogy van egy Personosztályunk és egy introduce()metódusunk, amely bemondja a személy nevét és életkorát. Továbbá az életkor szövegként vagy számként is megadható.

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);
   }
}
Már ismerjük a túlterhelést, így tudjuk, hogy mindkét módszer úgy fog viselkedni, ahogy kell: A nevem Alex. Huszonegy éves vagyok. A nevem Mary. 32 éves a korom. De mi lesz, ha nullkarakterlánc vagy szám helyett második paraméterként adjuk meg?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
Összeállítási hibát fogunk kapni! Mi okozza ezt, és pontosan mi a "kétértelműség"? Valójában minden nagyon egyszerű. A probléma az, hogy a metódusnak két változata van: az egyikben Stringa második argumentum, a másikban pedig Integera második argumentumként. De a Stringés egy Integeris lehet null! Mivel ezek referenciatípusok, nullmindkettő alapértelmezett értéke. Ezért ebben a helyzetben a fordító nem tudja kitalálni, hogy a metódus melyik verzióját kell meghívnia. A probléma megoldása meglehetősen egyszerű. Nullkifejezetten átalakítható egy adott referenciatípusra. Így metódus hívásakor zárójelben megadhatja a második argumentumhoz kívánt adattípust! A fordító megérti a "tippjét", és meghívja a helyes metódust:

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);
   }
}
Kimenet: Módszer két sztringgel! A nevem Victor. Az életkorom null. Vegye figyelembe, hogy ha a számparaméter primitív int, nem pedig az Integer hivatkozástípus példánya, akkor nem történt volna ilyen hiba.

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);
   }
}
Kitalálod miért? Ha kitaláltad, hogy miért, akkor jó! :) Mert primitívek nem lehetnek null. introduce()Most már csak egy választása van a fordítónak, azaz két karakterlánccal hívja meg a metódust. Ez a metódus azon verziója, amely a metódus minden meghívásakor futni fog.

További olvasnivalók:

Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION