"Hej, Amigo! För ett par dagar sedan berättade jag om överbelastningsmetoder. Förstod du allt?"
"Ja. Jag kommer ihåg. Varje klassmetod måste vara unik. En medlemsmetod är unik om klassen inte har någon annan metod med samma namn och parametertyper (och ordningen på parametrarna spelar roll)."
"Mycket bra! Jag ser att du har lärt dig den läxan bra. Idag vill jag utöka dina kunskaper i det här ämnet lite. Vilken metod tror du kommer att kallas i varje enskilt fall?"
class Cat
{
public static void print(int n)
{
System.out.println(n);
}
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void print(String s)
{
System.out.println(s);
}
public static void main(String[] args)
{
Cat.print(1);
Cat.print((byte)1);
Cat.print("1");
Cat.print(null);
}
}
"Det är svårt att säga."
"I det första fallet är 1 en int . Vi har en 100% matchning med metoden som tar en int. Den första void print(int n). kommer att anropas.
I det andra fallet har vi ingen metod som tar en byte. Men det finns två metoder som tar en kort och en int. Baserat på regler för typbreddning kommer en byte först att breddas till en kort och sedan breddas till en int. Således är domen att tomrummet tryck (kort n). kommer att kallas.
I det tredje fallet har vi en 100% matchning med metoden som tar en sträng. Den tomma utskriften (String s). metoden kommer att kallas.
Det fjärde fallet är tvetydigt. null har inte en specifik typ. Kompilatorn kommer att vägra att kompilera den här koden . I det här fallet måste vi skriva Cat.print((Integer)null) för att anropa den tredje metoden och Cat.print((String)null) för att anropa den fjärde."
"Det var väldigt informativt. Tack."
"Jag skulle vilja påpeka att när man bestämmer den korrekta metoden att anropa kan typerna bara bredda sig. De kan inte begränsas. Tänk på det här exemplet:"
class Cat
{
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void main(String[] args)
{
Cat.print((byte)1);
Cat.print(1);
}
}
I det första fallet kommer bytetypen att breddas till en kort och den första metoden kommer att kallas: void print(short n). .
I det andra fallet kommer det att ske en implicit utvidgningskonvertering från int till heltal, och då kommer den andra metoden att kallas: void print(Integer n). .
— Det hade jag inte förväntat mig.
"Nej, här är den verkliga överraskningen:"
Java-kod | Beskrivning |
---|---|
|
I det första fallet kommer int att utökas till heltal. Eftersom det inte finns någon metod för heltal, är den mest lämpliga metoden (och den som kallas) void print(Object o)
I det andra fallet kommer det inte att finnas några kompileringsfel och void print(String s) kommer att anropas, vilket är något inte uppenbart. |
"Amigo, jag hoppas att du förstår att i sådana fall är det bäst att ange en typ av rolloperator (som vi gjorde med «(byte)») för att veta exakt vilken metod som kommer att kallas."
"Jag hade aldrig förväntat mig att några problem skulle komma från överbelastningsmetoder. Men sedan kommer du med. Tack, Rishi. Jag ska hålla mig på den här punkten."
GO TO FULL VERSION