JAVA PAGRINDAI DETALIAU
Java metodų perkrovimas
Metodų perkrovimas (angl. method overloading) leidžia klasėje aprašyti kelis vienodo pavadinimo metodus, jei skiriasi jų parametrų sąrašai. Ta pati aiški veiksmo sąvoka gali būti pritaikyta skirtingam argumentų skaičiui ar tipui.
Paprastas pavyzdys: skirtingas parametrų skaičius
class Skaiciuotuvas {
int sudeti(int pirmas, int antras) {
return pirmas + antras;
}
int sudeti(int pirmas, int antras, int trecias) {
return pirmas + antras + trecias;
}
}
Skaiciuotuvas skaiciuotuvas = new Skaiciuotuvas();
System.out.println(skaiciuotuvas.sudeti(4, 6));
System.out.println(skaiciuotuvas.sudeti(4, 6, 5));10
15
- Abu metodai vadinasi
sudeti, nes abu atlieka tą patį veiksmą. - Pirmasis priima du
intparametrus, todėl tinka iškvietimuisudeti(4, 6). - Antrasis priima tris parametrus, todėl tinka iškvietimui
sudeti(4, 6, 5). - Kompiliatorius tinkamą metodą pasirenka dar prieš paleidžiant programą.
Skirtingi parametrų tipai
class KainosSpausdintuvas {
void rodyti(int eurai) {
System.out.println("Kaina: " + eurai + " Eur");
}
void rodyti(double eurai) {
System.out.printf("Kaina: %.2f Eur%n", eurai);
}
}
KainosSpausdintuvas spausdintuvas = new KainosSpausdintuvas();
spausdintuvas.rodyti(12);
spausdintuvas.rodyti(12.5);Kaina: 12 Eur
Kaina: 12.50 Eur
- Sveikajam skaičiui
12tiksliai tinka metodas suintparametru. - Reikšmei
12.5reikia metodo sudoubleparametru. - Metodai gali turėti skirtingą vykdomą kodą, tačiau jų bendras pavadinimas parodo tą pačią paskirtį – parodyti kainą.
Skirtinga parametrų tvarka
class Pristatymas {
void registruoti(String miestas, int pastoKodas) {
System.out.println(miestas + ", " + pastoKodas);
}
void registruoti(int pastoKodas, String miestas) {
System.out.println(pastoKodas + ", " + miestas);
}
}
Pristatymas pristatymas = new Pristatymas();
pristatymas.registruoti("Kaunas", 44280);
pristatymas.registruoti(92118, "Klaipėda");Kaunas, 44280
92118, Klaipėda
Parašai registruoti(String, int) ir registruoti(int, String) yra skirtingi, todėl Java juos leidžia. Vis dėlto tokie panašūs variantai gali klaidinti žmogų. Jei argumentų prasmė iš iškvietimo neaiški, geriau rinktis skirtingus, aiškesnius metodų vardus.
Kas sudaro metodo parašą?
| Pakeitimas | Ar sukuriamas kitas perkrovimas? | Kodėl? |
|---|---|---|
| Parametrų skaičius | Taip | Iškvietimai turi skirtingą argumentų skaičių |
| Parametrų tipai | Taip | Kompiliatorius gali parinkti pagal argumentų tipus |
| Parametrų tipų tvarka | Taip | Gaunamas kitas parametrų sąrašas |
| Parametrų vardai | Ne | Vardai nėra metodo parašo dalis |
| Grąžinamasis tipas | Ne | Java negali pasirinkti metodo vien pagal laukiamą rezultatą |
| Prieigos modifikatorius | Ne | public ar private metodo parašo nekeičia |
Tiksliausias atitikmuo ir skaitinio tipo platinimas
class Matavimas {
void rodyti(int reiksme) {
System.out.println("int: " + reiksme);
}
void rodyti(double reiksme) {
System.out.println("double: " + reiksme);
}
}
Matavimas matavimas = new Matavimas();
short trumpasSkaicius = 7;
matavimas.rodyti(5);
matavimas.rodyti(5.5);
matavimas.rodyti(trumpasSkaicius);int: 5
double: 5.5
int: 7
5yraint, todėl pasirenkamas tiksliai sutampantis variantas.5.5yradouble, todėl pasirenkamas antras metodas.shortvarianto nėra, todėl Java saugiai išplečiashortįint.- Jei įmanomi keli variantai, kompiliatorius ieško konkrečiausio tinkamo atitikmens.
Dviprasmiškas iškvietimas
class Pastaba {
void issaugoti(String tekstas) { }
void issaugoti(StringBuilder tekstas) { }
}
Pastaba pastaba = new Pastaba();
// Klaida: null tinka abiem metodams
pastaba.issaugoti(null);Kodas nesukompiliuojamas: null gali būti ir String, ir StringBuilder nuoroda, o nė vienas tipas čia nėra aiškiai tinkamesnis.
Per daug panašių perkrovimų apsunkina naudojimą. Metodo API turėtų būti ne tik techniškai leidžiamas, bet ir lengvai suprantamas.
Galima perkrauti ir statinius metodus
class Tekstas {
static String sujungti(String pirmas, String antras) {
return pirmas + " " + antras;
}
static String sujungti(String pirmas, String antras, String trecias) {
return pirmas + " " + antras + " " + trecias;
}
}
System.out.println(Tekstas.sujungti("Labas", "Ieva"));
System.out.println(Tekstas.sujungti("Gražios", "tau", "dienos"));Labas Ieva
Gražios tau dienos
Perkrovimas galioja ir egzemplioriaus, ir static metodams. Svarbiausia, kad vienodo pavadinimo metodų parametrų sąrašai būtų skirtingi.
Kodėl tai vadinama kompiliavimo laiko polimorfizmu?
Kompiliatorius iš argumentų jau gali nustatyti, kurį perkrautą metodą kviesti. Pasirinkimas nėra paliekamas vykdymo laikui. Dėl to metodų perkrovimas dar vadinamas statiniu arba kompiliavimo laiko polimorfizmu.
Perkrovimas reiškia kelis vienodo vardo, bet skirtingų parametrų metodus. Perrašymas (overriding) vyksta paveldėjime, kai poklasis pateikia savo paveldėto metodo įgyvendinimą.
Metodų ir konstruktorių perkrovimas
| Savybė | Metodų perkrovimas | Konstruktorių perkrovimas |
|---|---|---|
| Paskirtis | Leisti atlikti panašų veiksmą su skirtingais duomenimis | Leisti skirtingais būdais sukurti objektą |
| Pavadinimas | Tas pats metodo vardas | Visada klasės vardas |
| Grąžinamasis tipas | Yra, tačiau perkrovimo nenulemia | Nerašomas |
| Iškvietimas | Per objektą arba klasę, jei metodas static | Dažniausiai su new |
Ką verta prisiminti?
- Perkrauti metodai turi tą patį pavadinimą ir skirtingus parametrų sąrašus.
- Galima keisti parametrų skaičių, tipus arba jų tvarką.
- Parametrų vardai ir grąžinamasis tipas perkrovimo nesukuria.
- Kompiliatorius renkasi tiksliausią galimą atitikmenį.
- Java gali atlikti saugų primityviojo tipo išplėtimą, jei tikslaus varianto nėra.
- Venk perkrovimų, kuriuos žmogui arba kompiliatoriui lengva supainioti.

