aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes over loaded methods?? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "over loaded methods??" Watch "over loaded methods??" New topic
Author

over loaded methods??

nachiket deshpande
Ranch Hand

Joined: Oct 06, 2000
Posts: 114
pl.look at the following code
class mammal{
void eat(mammal m){
System.out.println("mammal");
}
}
class cattle{
void eat(cattle c){
System.out.println("cattle")
}
}
class horse{
void eat(horse h){
System.out.println("horse")
}
}
public class animal{
public static void main(String[] args){
mammal m=new horse();
cattle c=new horse();
horse h=new horse();
c.eat(m); //last line
}
}
look at the last line..
the o/p is "mammal"
if i call h.eat(c);the o/p is "cattle"
if i call c.eat(h); the o/p is "cattle"
can some one help me how the overloaded methods are called here???
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by nachiket deshpande:
pl.look at the following code
class mammal{
void eat(mammal m){
System.out.println("mammal");
}
}
class cattle{
void eat(cattle c){
System.out.println("cattle")
}
}
class horse{
void eat(horse h){
System.out.println("horse")
}
}
public class animal{
public static void main(String[] args){
mammal m=new horse();
cattle c=new horse();
horse h=new horse();
c.eat(m); //last line
}
}
look at the last line..
the o/p is "mammal"
if i call h.eat(c);the o/p is "cattle"
if i call c.eat(h); the o/p is "cattle"
can some one help me how the overloaded methods are called here???

Hello,
I don't quite understand how to relate the three classes that you described. The only thing that they seem to relate to each other is thorugh human lanaguage. However in jave, they are not related unless they all extend from a common superclass. In your case, there is no such tie, so I would bet that the compiler will choke when you try to initialize one object and declare as another (i.e
mammal m = new horse(); or
cattle c = new horse(); is a no-no
just like
float f = 2.3; is unacceptable to java compiler.
Regards,
Lam
Stevie Kaligis
Ranch Hand

Joined: Feb 04, 2001
Posts: 400
It doesn't even compile !!!
aren't you missing something ???
stevie
nachiket deshpande
Ranch Hand

Joined: Oct 06, 2000
Posts: 114
yes! the code compiles
Amitabh Yadav
Greenhorn

Joined: Apr 07, 2001
Posts: 13
Hi There,
I agree with lam here that there is no relation as such i think animal should be the superclass of every class out here & then the relationship is made quite nicely & after that we can discuss the question .ABout compilation yes its giving me problems too.
take care

------------------
nachiket deshpande
Ranch Hand

Joined: Oct 06, 2000
Posts: 114
Sorry Sorry...extremely sorry for giving the wrong code!!!
yes the cattle class extends mammal and horse class extends cattle.

class mammal{
void eat(mammal m){
System.out.println("mammal");
}
}
class cattle extends mammal{
void eat(cattle c){
System.out.println("cattle");
}
}
class horse extends cattle{
void eat(horse h){
System.out.println("horse");
}
}
public class animal{
public static void main(String[] args){
mammal m=new horse();
cattle c=new horse();
horse h=new horse();
m.eat(c);
c.eat(h);
h.eat(c);
}
}
can someone help me now..

Ajith Kallambella
Sheriff

Joined: Mar 17, 2000
Posts: 5782
Nachiket,
What is that you are unable to understand in this program??
There is no overloading involved here since each class just has just one method. There is is no overriding either since the method signatures defined by each class is different.
Also I could not comprehend the significance of arguments being passed to the eat() method. If you would like to test overriding, just make all the eat() methods to take no arguments. This will make the signature of the eat() method exactly the same in all the subclasses.
Hope that helps!
------------------
Ajith Kallambella M.
Sun Certified Programmer for the Java�2 Platform.
IBM Certified Developer - XML and Related Technologies, V1.


Open Group Certified Distinguished IT Architect. Open Group Certified Master IT Architect. Sun Certified Architect (SCEA).
farooqmali
Greenhorn

Joined: Apr 01, 2001
Posts: 8
Hi,
You brought nice point here, according to me, there is no problem at all in overloading it is working as it suppose to.
I think you better work on concept of Inheritance.
m.eat(c); // is printing out "mammal" it is fine.
c.eat(h); // is printing out "cattle" it is fine.
h.eat(c); // again it is priting out printing "cattle" cos eat method is comming from supper class which is cattle, as horse is extending cattle calss.
So make it simple with more generic problem and work on Inheritance first.

Muhammad Ali Farooq
nachiket deshpande
Ranch Hand

Joined: Oct 06, 2000
Posts: 114
Hi Farooqmali
Can you please expalin me how the methods are called and also the output...
Rick Zhong
Greenhorn

Joined: Apr 13, 2001
Posts: 10
Hi nachiket,
the result coming out like these is because it has nothing to do with overriding or dynamic binding, the method eat() invoked according and ONLY according to the reference type!
however, i have a ques about overloading term itself, can we say the three eat() are OVERLOADING methods even though they are not defined within the same class!?
anyone can clarity it?
Rick
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by nachiket deshpande:
Hi Farooqmali
Can you please expalin me how the methods are called and also the output...

Hello Nachiket,
Before we study how the methods are called, let's review your code:
First, even though the method in each class has the same name, but they have different signature so there is no overriding nor overidden method involved here (i.e there is no polymorphism relation).
Second, because you specify that cattle is an extension of mammal, therefore, cattle class inherits method eat(mammal) from its parent (i.e. class cattle now can respond to two methods namely eat(mammal) and eat(cattle)).
Third, because you specify that horse is an extension of cattle, which is an extension of mammal, therefore, horse class inhertits both eat(cattle) from cattle class and eat(mammal) from mammal class (i.e. class horse now can respond to three mthods namely eat(mammal), eat(cattle), and eat(horse)).
So if you print m.eat(cattle c), you infact tell java to "invoke method eat() that belongs to class mammal." That is what the instant 'n' stands for. That is why you get "mammal". BTW, since cattle is subclass of mammal, you can pass it in as an argument and got no complier error. That may create a confusion because it appears that you invoke eat(cattle c) method in cattle class, using the cattle signature as reference.
Now when you invoke c.eat(cattle c) or c.eat(horse h), you would get an answer of "cattle" for the same reason stated above (i.e you invoke eat() method in cattle class, That what 'c.' stands for).
Finally when you invoke h.eat(cattle c), you would get the answer of "cattle", because remember that horse inherits eat(cattle) and eat(mammal) due to the extension that you set up. So class horse can response to three different eat()'s. Therefore, in this case the signature or the argument will dictate what method is to be called -> and that means eat( cattle c) will be invoked, hence the answer of "cattle." To be clear, let's llok at the following code:
public class test {
public static void main(String[] args) {
A myA = new A();
A.printme ("hello");
}
}
class A{
static void printme (int i){
System.out.println("print Interger");
}

static void printme (String str) {
System.out.println("print String");
}
}
The result would print "print String" because the argument will dictate what method is to be invoked. Note "hello" is not printed, in this code it acts only as the method identifer (sort of - I kind of strech it, but you got the point), which is String type.

Hope my answer helps.
Take care,
Lam
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by Rick Zhong:
Hi nachiket,
the result coming out like these is because it has nothing to do with overriding or dynamic binding, the method eat() invoked according and ONLY according to the [b]reference type!

however, i have a ques about overloading term itself, can we say the three eat() are OVERLOADING methods even though they are not defined within the same class!?
anyone can clarity it?
Rick[/B]

Hi Rick,
I would say so from the subclass's point of view - but not from the superclass's point of view since the parent class do not see the method of its subclass... That is why when we assign an object of parent to that of a child type variable, we will eventually get RuntimeException because the parent class on RHS of the assignment knows nothing about the extended fields and/or methods of the subclass.
Am I wrong? Anyone?
Thanks,
Lam
Rick Zhong
Greenhorn

Joined: Apr 13, 2001
Posts: 10
hi, Lam,
runtime error here is an Undowncastable problem, here is the term of 'overloading' defined by jls:

If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but different signatures, then the method name is said to be overloaded. This fact causes no difficulty and never of itself results in a compile-time error. There is no required relationship between the return types or between the throws clauses of two methods with the same name but different signatures.

Rick
nachiket deshpande
Ranch Hand

Joined: Oct 06, 2000
Posts: 114
Thanks a lot Lam Thai!!i got it.
Bob Vel
Greenhorn

Joined: Mar 21, 2001
Posts: 24
Hello Lam Thai
According to your answer
So if you print m.eat(cattle c), you infact tell java to "invoke method eat() that belongs
to class mammal." That is what the instant 'n' stands for. That is why you get "mammal".

When I run this following code I am getting output as
cattle
cattle
cattle
Why?
As per your answer, I thought it should print
cattle1
cattle
cattle
Please explain.
class mammal
{
void eat(mammal m)
{
System.out.println("mammal");
}
void eat(cattle c)
{
System.out.println("cattle1");
}
}
class cattle extends mammal
{
void eat(cattle c)
{
System.out.println("cattle");
}
}
class horse extends cattle
{
void eat(horse h)
{
System.out.println("horse");
}
}

public class animal
{
public static void main(String[] args)
{
mammal m=new horse();
cattle c=new horse();
horse h=new horse();
m.eat(c);
c.eat(h);
h.eat(c);
}
}
Thanks in advance.


Without involvement, there is no commitment. Mark it down, asterisk it, circle it, underline it.<BR>No involvement, no commitment.
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by Bob Vel:
Hello Lam Thai
According to your answer
So if you print m.eat(cattle c), you infact tell java to "invoke method eat() that belongs
to class mammal." That is what the instant 'n' stands for. That is why you get "mammal".

When I run this following code I am getting output as
cattle
cattle
cattle
Why?
As per your answer, I thought it should print
cattle1
cattle
cattle
Please explain.
class mammal
{
void eat(mammal m)
{
System.out.println("mammal");
}
void eat(cattle c)
{
System.out.println("cattle1");
}
}
class cattle extends mammal
{
void eat(cattle c)
{
System.out.println("cattle");
}
}
class horse extends cattle
{
void eat(horse h)
{
System.out.println("horse");
}
}

public class animal
{
public static void main(String[] args)
{
mammal m=new horse();
cattle c=new horse();
horse h=new horse();
m.eat(c);
c.eat(h);
h.eat(c);
}
}
Thanks in advance.

Hi Bob,

Before I explain, please remember the overriding or dynamic binding concept first. It requires that the superclass and subclass to have mehtods with the same name and same signatures. That concept must be understood first. My statement that you quote, "invoke method eat() that belongs to class mammal." That is what the instance 'm' stands for. That is why you get "mammal", only applies when there is no dynamic binding!!! which my original answer tries to make clear right at the bat.
With that, let's take a look at your code.
It is different, you added a method eat(cattle) in mammal class. By doing this, you now create a dynamic biding condition in which eat(cattle) in cattle class now overrides eat(cattle) in mammal. before there is no dynamic binding because the signature or the argument of all the eat()'s are not the same. In your case, eat(cattle) in mammal and eat(cattle) in cattle have the same name and the same signature/argument, hence the behavior is now different between your code and the previous one.
Even the code is different, but the inheritant principal still holds true. If you look from class horse, it still inherits methods from its superclass, cattle and those from mamal class. So it can now respond to its own eat(horse), but it also can respond to eat(mammal) in mammal and eat(cattle) in cattle.
Because eat(cattle) in cattle overrides eat(cattle) in mammal, therefore m.eat(cattle) will invoke the eat(cattle) in cattle class due to dynamic binding. Hence the answer "cattle". If you remove eat(cattle) in mammal class, the dynamic binding disappears between mammal and cattle, you will get "mammal". In your code, the only way to get "cattle1" is to use super in class cattle (i.e super.eat(cattle)).
The answer for c.eat(horse) will be "cattle" since there is no dynamic binding involved (i.e there is no overriding method between class cattle and class horse.)
The answer for h.eat(cattle) was given in previous reply.
If you remove the eat(cattle) from mammal class, then there is no overriding-overriden or dynamic binding relationship. In that case you will get the (mammal, cattle, cattle) as the answers in your main().
Hope that helps.
Take care,
Lam

[This message has been edited by Lam Thai (edited April 18, 2001).]
Sathi Chowdhury
Ranch Hand

Joined: Mar 16, 2001
Posts: 52
Ur explanation is great!!
ratul banji
Ranch Hand

Joined: Mar 15, 2001
Posts: 108
Hi Bob,
If u want that o/p ..then try it. It will give the o/p which u want.

class mammal
{
static void eat(mammal m)
{
System.out.println("mammal");
}
static void eat(cattle c)
{
System.out.println("cattle1");
}
}
class cattle extends mammal
{
static void eat(cattle c)
{
System.out.println("cattle");
}
}

class horse extends cattle
{
static void eat(horse h)
{
System.out.println("horse");
}
}

public class isitover{
public static void main(String[] args)
{
mammal m= new cattle();
cattle c= new horse();
horse h=(horse) c;
m.eat(c);
c.eat(h);
h.eat(c);
}
}
This will give :
cattle1
cattle
cattle

Hope that helps.
<marquee> Ratul Banerjee </marquee>
ratul banji
Ranch Hand

Joined: Mar 15, 2001
Posts: 108
Hi lam,
I want some more explanation 4rm u.All that u explain is quite good.
But...pls,explain me this portion1ce again.That will be very kind of u.
<quote>
Now when you invoke c.eat(cattle c) or c.eat(horse h), you would get an answer of "cattle" for the same reason stated above (i.e you invoke eat() method in cattle class, That what 'c.' stands for).
</quote>
In the case of horse:
The class horse can response to three different eat()'s. Therefore, in this case the signature or the argument will dictate what method is to be called. why it is not heppening for 'cattle' also ....as cattle also can response to 2 different eat()'s ?
Thanks in adv.
Regds.
<marquee> Ratul Banerjee </marquee>
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by ratul banji:
Hi lam,
I want some more explanation 4rm u.All that u explain is quite good.
But...pls,explain me this portion1ce again.That will be very kind of u.
<quote>
Now when you invoke c.eat(cattle c) or c.eat(horse h), you would get an answer of "cattle" for the same reason stated above (i.e you invoke eat() method in cattle class, That what 'c.' stands for).
</quote>
In the case of horse:
The class horse can response to three different eat()'s. Therefore, in this case the signature or the argument will dictate what method is to be called. why it is not heppening for 'cattle' also ....as cattle also can response to 2 different eat()'s ?
Thanks in adv.
Regds.
[b]<marquee> Ratul Banerjee
</marquee>
[/B]

Hi friend,
This thread is getting hot for the reason I don't quote understand. But back to your question. Assuming yout question addresses the first set of code where there is no dynamic binding.
For class horse, since there is no dynamic binding (i.e different signature), you will get:
"mammal" for h.eat(mammal) - This comes from class mammal's eat()
"cattle" for h.eat(cattle) - This comes from class cattle's eat()
"horse" for h.eat(horse) - it's own eat method
Again, these happen when there is no dynamic binding. In contrary, in the second set of code from Bob, there is eat(cattle) in both class mammal and class cattle. So when one says m.eat(cattle), one invokes eat(cattle) in class cattle instead.
Regards,
Lam
Shah Chunky
Ranch Hand

Joined: Dec 27, 2000
Posts: 116
Hi Lam...
Can v say that Overloaded Methods r invoked using the reference type & not the type of object it referrs to as in case of Overriding.
Also i have made some changes in the code & it is giving me a strange error can u help me...
class mammal
{
void eat(mammal m)
{
System.out.println("mammal");
}
}
class cattle extends mammal
{
void eat(cattle c)
{
System.out.println("cattle");
}
}
class horse extends cattle
{
void eat(mammal m)
{
System.out.println("Mam Cat");
}
/*void eat(cattle c)// Commenting this method gives CTE
{
System.out.println("Cat");
}*/
void eat(horse h)
{
System.out.println("horse");
}
}
public class Animal2
{
public static void main(String[] args)
{
mammal m=new cattle();
cattle c=new cattle();
horse h=new horse();

m.eat(h);
c.eat(m);
h.eat(c);
System.out.println();
}
}
It gives me the below Error at Compile time
Animal2.java:41: Reference to eat is ambiguous. It is defined in void eat(mammal) and void eat(cattle).
If i remove the Comment it works fine.
Thanks in adv


Shah Chunky - Sun Certified Java2 Programmer.
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by Shah Chunky:
Hi Lam...
Can v say that Overloaded Methods r invoked using the reference type & not the type of object it referrs to as in case of Overriding.
Also i have made some changes in the code & it is giving me a strange error can u help me...
class mammal
{
void eat(mammal m)
{
System.out.println("mammal");
}
}
class cattle extends mammal
{
void eat(cattle c)
{
System.out.println("cattle");
}
}
class horse extends cattle
{
void eat(mammal m)
{
System.out.println("Mam Cat");
}
/*void eat(cattle c)// Commenting this method gives CTE
{
System.out.println("Cat");
}*/
void eat(horse h)
{
System.out.println("horse");
}
}
public class Animal2
{
public static void main(String[] args)
{
mammal m=new cattle();
cattle c=new cattle();
horse h=new horse();

m.eat(h);
c.eat(m);
h.eat(c);
System.out.println();
}
}
It gives me the below Error at Compile time
Animal2.java:41: Reference to eat is ambiguous. It is defined in void eat(mammal) and void eat(cattle).
If i remove the Comment it works fine.
Thanks in adv


Hi Shah,
When you add method void eat(mammal) in class horse and comment out method eat(cattle), class horse now sees
a) its own void eat(mammal) and
b) void eat(cattle) from class cattle
Cattle is derived from mammal - so by saying h.eat(cattle) do you want the compiler to use horse's eat(mammal) or horse's inheritted cattle's eat(cattle)? Hence compiler does not know how to resolve the ambiquity.
When you add void eat(cattle) back in class horse, such ambiguity is removed since dynamic binding clearly would select the overriding method.
With eat(cattle) commented out in horse, try one of these ideas:
a) commenting out eat(mammal) in horse or
b) replacing h.eat(c) with h.eat(m)
What do you see?
Take care,
Lam
vivek bawge
Greenhorn

Joined: Apr 19, 2001
Posts: 24
Lam,
Thanks for your nice explanation. But i have another doubt here.
Does overloading methods belonging to the same class and overloading methods in the class with the methods derived from the base class work differently? Why?
I thought that all the base class methods come in the name space and scope of derived class. (Ignoring overriding also)
I mean, if compiler is confused now when the two methods are in the same class, then, why it could resolve the call in the original example, when 1 method was in horse and another in cattle.
Thanks in advance,
Vivek
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by vivek bawge:
Lam,
Thanks for your nice explanation. But i have another doubt here.
Does overloading methods belonging to the same class and overloading methods in the class with the methods derived from the base class work differently? Why?
I thought that all the base class methods come in the name space and scope of derived class. (Ignoring overriding also)
I mean, if compiler is confused now when the two methods are in the same class, then, why it could resolve the call in the original example, when 1 method was in horse and another in cattle.
Thanks in advance,
Vivek

Hello Vivek,
First, may we take a look at the following code snippet first:
class mammal {}
class cattle extends mammal {}
class horse extends cattle {
void eat(mammal) {
System.out.println ("Mammal in horse");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal()); h.eat(new cattle()); h.eat(h);
}
}
What do you think that snippet of code will print? That is right! Three strings of "Mammal in horse."
Now if you add void eat(cattle) and void eat(horse) in class horse as follows:
class horse extends cattle {
void eat(mammal) {
System.out.println ("Mammal in horse");
}
void eat(cattle) {
System.out.println ("Cattle in horse");
}
void eat(horse) {
System.out.println ("Horse in horse");
}
}
What do you expect the print out would look like?
Here is the answer:
"Mammal in horse"
"Cattle in horse"
"Horse in horse"
So overloading feature does work as expected (i.e. the signature will determine what method in horse to be invoked).
Notice that up to now neither class mammal nor class cattle has any method at all.
Now let's add the following code:
To mammal add:
void eat(mammal) { System.out.println("Mammal in mammal"); } }
To cattle add:
void eat(cattle) { System.out.println("Cattle in cattle"); } }
Recompile and run the code again, what do you see?
"Mammal in horse"
"Cattle in horse"
"Horse in horse"
The same answer as before, nothing changed! Why is that? The answer lies in the fact that the two eat()'s we've just added in
were overriden by those in class horse.
Now if we remove all eat()'s from cattle and horse and leave only eat() in mammal. What would the code print? The answer is three "Mammal in mammal." Why is that? Inheritance takes effect! Class horse even has no method but it does inherit eat(mammal) from the superclass of its superclass.
Now to cattle add back:
void eat(cattle) { System.out.println("Cattle in cattle"); } }
This will yield:
"Mammal in mammal" for h.eat(new mammal())
"Cattle in cattle" for h.eat(new cattle())
"Cattle in cattle" for h.eat(h);
As you can see, since horse has no method, it will invoke whichever inheritted method that is closest to it from ancestry tree viewpoint. In this case cattle is what horse derives from.
So far I hope that you see the effect of overloading, overriding , and inheritance.
Now to horse add back:
void eat(mammal) { System.out.println("Mammal in horse"); } }
So now the whole program look like this:
class mammal {
void eat(mammal) {System.out.println ("Mammal in mammal");}
}
class cattle extends mammal {
void eat(cattle) {System.out.println ("Cattle in cattle");}
}
class horse extends cattle {
void eat(mammal) {
System.out.println ("Mammal in horse");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal()); h.eat(new cattle()); h.eat(h);
}
}
Now the compiler will choke. Why? it has nothing to do with overloading working different in the same class or across ancestry tree. It simply causes an ambiguity! Let's look again our first snippet of code:
class mammal {}
class cattle extends mammal {}
class horse extends cattle {
void eat(mammal) {
System.out.println ("Mammal in horse");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal()); h.eat(new cattle()); h.eat(h);
}
}
We can pass in either mammal or cattle or horse object, the horse's eat(mammal) will be invoked because the compiler see that such method can take either mammal, cattle or horse as its argument.
So now with the presence of eat(cattle) in cattle, what method should the compiler choose for h.eat(cattle) or h.eat(h)? Would it be eat(mammal) in horse as just stated? or would it be eat(cattle) in cattle due to inheritance? The compiler tells us, right? .... It does not like to deal with this kind of ambigutity.
By the way, I am not part of the Java compiler team and do not know the reason why they made the language behave the way it behaves. But I hope that with this reply and the snippets of code that I've walked through, you might find the logic behind the whole overloading, overriding, and inheritance concepts.
Opinion anyone? Maybe a better and more concise explanation?
Regards,
Lam

vivek bawge
Greenhorn

Joined: Apr 19, 2001
Posts: 24
Hi Lam,
thanks for the elaborated reply. And i do follow the concepts after each code snippet. I am sorry but when i put together 2 code snippets it doesnt make much sense to me. And as per your concluding remark, it doesnt have anything with the combined effect of overlading and inheritence. But i realize that things are little different though. Lets forget about the world and some other supporting examples and just look at the 2 examples below.
I would appreciate if you just tell me the brief answer as to why compiler gets confused in the first case and resolves the second case.
THE ONLY DIFFERENCE IS in the case1 eat(Cattle) is in the base class Cattle and in case 2 eat(Cattle) is in the derived class Horse. But Either way isnt it part of Horse ( because in case 1 also its derived from the base class Cattle).

//case 1
class mammal {
}
class cattle extends mammal {
void eat(cattle c) {System.out.println ("Cattle in cattle");}
}
class horse extends cattle {
void eat(mammal m) {
System.out.println ("Mammal in horse");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal());
h.eat(new cattle());
h.eat(h);
}
}

//case 2
class mammal {
}
class cattle extends mammal {
}
class horse extends cattle {
void eat(mammal m) {
System.out.println ("Mammal in horse");
}
void eat(cattle c) {
System.out.println ("Cattle in cattle");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal());
h.eat(new cattle());
h.eat(h);
}
}


Thanks a lot for the patience.
Hope you will help me.
sincerely,
Vivek
Lam Thai
Ranch Hand

Joined: Apr 02, 2001
Posts: 117
Originally posted by vivek bawge:
Hi Lam,
thanks for the elaborated reply. And i do follow the concepts after each code snippet. I am sorry but when i put together 2 code snippets it doesnt make much sense to me. And as per your concluding remark, it doesnt have anything with the combined effect of overlading and inheritence. But i realize that things are little different though. Lets forget about the world and some other supporting examples and just look at the 2 examples below.
I would appreciate if you just tell me the brief answer as to why compiler gets confused in the first case and resolves the second case.
THE ONLY DIFFERENCE IS in the case1 eat(Cattle) is in the base class Cattle and in case 2 eat(Cattle) is in the derived class Horse. But Either way isnt it part of Horse ( because in case 1 also its derived from the base class Cattle).

//case 1
class mammal {
}
class cattle extends mammal {
void eat(cattle c) {System.out.println ("Cattle in cattle");}
}
class horse extends cattle {
void eat(mammal m) {
System.out.println ("Mammal in horse");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal());
h.eat(new cattle());
h.eat(h);
}
}

//case 2
class mammal {
}
class cattle extends mammal {
}
class horse extends cattle {
void eat(mammal m) {
System.out.println ("Mammal in horse");
}
void eat(cattle c) {
System.out.println ("Cattle in cattle");
}
}
class Demo {
public static void main(String[] args) {
horse h = new horse();
h.eat(new mammal());
h.eat(new cattle());
h.eat(h);
}
}


Thanks a lot for the patience.
Hope you will help me.
sincerely,
Vivek

Hello Vivek,
Okay :-) Here we go.
First, you get compilation error complaining about both h.eat(new cattle()) and h.eat(h) in case #1, right? So let's take a look at the 1st statement. It is composed of three parts:
h - the object of type horse created via horse h = new horse();
eat() - the method
new cattle() - the object of type cattle
So when the compiler sees this, it would first look into class horse (via h) to see if there is such eat() method that takes an object reference of type cattle. In case #2, there is one that matches exactly, hence the compiler uses it and we have no problem. Even if there is another eat(cattle) in class cattle, you won't get a compilation error because eat(cattle) in class will override its parent's method. Here neither overriding, nor overloading feature would present any problem. The choice of which method to bind to is too obvious.
But when it does not find such exact match, what does it do? It would have to select an alternative, right?
So in case #1, it now has two 'not-quite' perfect choices, namely its own eat(mammal) and its parent's eat(cattle). It can either select the former or a later without violating any rule. Two imperfect choices and no clear cut... thus the compiler does not know how to deal with it.
Note that this could be changed by the Java compiler designers to force it to make the choice. But as it stands right now, you have found a case where the compiler could not make up its mind and therefore it asks for your help.
By the way, if you are one of the java compiler designers, which way would you choose - eat(mammal) in horse or eat(cattle) in cattle?
Regards,
Lam

[This message has been edited by Lam Thai (edited April 25, 2001).]
vivek bawge
Greenhorn

Joined: Apr 19, 2001
Posts: 24
Thanks,
yeah i can figure out what the compiler does but i cant figure out why it does so? as u said it depends on the whim of the compiler designers.
i would definitely choose eat(Cattle) in Cattle because when a programmer inherits from a class, unconditionally, he wants to inherit the whole functionality in the base class as if its own.
Just imagine, how beautifully C++ might have resolved this case.
Isnt java different in some cases. and just imagine what happens when an exception handler in java throws an exception.
Thanks,
Vivek
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: over loaded methods??