Showing posts with label overloading. Show all posts
Showing posts with label overloading. Show all posts

Sunday, October 25, 2009

no operator overloading in java? tell it to + operator

Lets begin with the wikipedia definition of operator overloading.

In computer programming, operator overloading (less commonly known as operator ad-hoc polymorphism) is a specific case of polymorphism in which some or all of operators like +, =, or == have different implementations depending on the types of their arguments.



It's generally thought that Java does not support operator overloading which is not true.
Take a look at + operator.



int two = 2;
int six = 6;

int sum = two + six;

System.out.println(sum); // output is 8



Quite expected right? I give two operands (two and six) and + operator adds them together. What if I use strings as operands?


String a = "avenged";
String b = "sevenfold";

String result = a + b;

System.out.println(result); // output: avengedsevenfold


+ operator concatenates two strings. As you can easily see + operator has different implementations depending on the type of operands.
Now, lets take a look at some gotchas of the + operator.
What if I mix different types of operands?


int two = 2;
int six = 6;

String str = "depechemode";

System.out.println(two + six + str);

System.out.println(two + str + six);

System.out.println(str + two + six);


The outputs are quite interesting. Let me explain you how it's processed. From left to right it's inspected if there are any strings as operands. As long as I don't see a string I treat + as addition but when I see one I begin to treat every subsequent operand as strings and I concatenate them.

So I have two + six which are two integers. I add them together which makes 8. Then I see a string and treat 8 as a string and concatenate it with str which in result gives "8depechemode".

Later I have two + str. str is a String so two will be treated like one. As I saw a string I treat all of the rest as strings and concat them. The result is "2depechemode6".

For the last example, we see a string as the first operand. We will begin treating every operand as strings and concat them so I'll have "depechemode26" as result.

I hope that everything is clear for + operator and its overloading capabilities.

Wednesday, August 12, 2009

method overloading in java (with umberto tozzi)

Method overloading allows you to use the same method name with different arguments. As long as the "different arguments" constraint holds, you are free to change the return type, the access modifier and the thrown exception of the method. Lets see it on an example.


private void sings(String lyrics){
System.out.println("Tozzi sings these lyrics: "+lyrics);
}

public void sings(int times){
System.out.println("Tozzi sings "+times+" times");
}



I'm free to change the access modifier private to public of the overloaded method as long as I use another argument type in the method.



private void sings(String lyrics){
System.out.println("Tozzi sings these lyrics: "+lyrics);
}

String sings(int times){
String message = "Tozzi sings "+times+" times";
System.out.println(message);
return message;
}


Above I change the access modifier (from private to package access) and the return type (from none to String).


private void sings(String lyrics){
System.out.println("Tozzi sings these lyrics: "+lyrics);
}

private void sings(boolean isUmbertoSick) throws Exception{
if(isUmbertoSick)
throw new Exception("Umberto Tozzi is sick");

System.out.println("Tozzi sings 'Ti amo'");
}


Above I added an exception to the overloaded method. The method checks if Umberto Tozzi is sick and throws an exception in this case. If he's ok, Umberto gladly sings his hit single "Ti Amo".

An interesting case is when you overload methods which have two classes with superclass, subclass relationship between (one class inherits the other) as argument. Lets see it in an example.


class Song { }
class Ballad extends Song { }

public class UmbertoTozzi {

private void sings(String lyrics){
System.out.println("Tozzi sings these lyrics: "+lyrics);
}

private void sings(Song song){
System.out.println("Tozzi sings the song "+song);
}

private void sings(Ballad ballad){
System.out.println("Tozzi sings the ballad "+ballad);
}

public static void main(String[] args) {
// create UmbertoTozzi object
UmbertoTozzi tozzi = new UmbertoTozzi();
// create a Ballad and Song object
Ballad ballad = new Ballad();
Song song = new Song();
// give the ballad and song references to
// the sings method
tozzi.sings(ballad); /* output: Tozzi sings the ballad Ballad@a6aeed */
tozzi.sings(song); /* output: Tozzi sings the song Song@126804e */

// bind a Ballad object
//to a Song reference
Song newSong = new Ballad();

tozzi.sings(newSong);
/* output: Tozzi sings the song Ballad@b1b4c3 */
}
}


There are three overloaded methods above. One accepts arguments of type String, the other Song and the last one Ballad. Notice that Ballad extends Song which means that Ballad is a Song. Ballad is the subclass while Song is the superclass. The last output is quite confusing. I sent a Ballad object to the sings method. Why sings(Song song) is called instead of sings(Ballad ballad) ? The answer is quite plain. The object related to the reference is not checked. If we put it in another way, the method call is done in compile time, not in runtime. So the compiler sees that the reference type is Song and it calls the corresponding method.
Long live Umberto Tozzi!