• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

over loaded methods??

 
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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???
 
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Ranch Hand
Posts: 400
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It doesn't even compile !!!
aren't you missing something ???
stevie
 
nachiket deshpande
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes! the code compiles
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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..

 
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
nachiket deshpande
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Farooqmali
Can you please expalin me how the methods are called and also the output...
 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot Lam Thai!!i got it.
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Lam Thai
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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).]
 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ur explanation is great!!
 
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Ranch Hand
Posts: 116
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Lam Thai
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic