wood burning stoves*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes inheritance confusion Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "inheritance confusion" Watch "inheritance confusion" New topic
Author

inheritance confusion

Bill Nelsen
Greenhorn

Joined: Aug 11, 2004
Posts: 27
I missed this problem on one of the practice tests and I just want to be sure that I understand the reasoning behind the answer correctly.


prints "Mammal eats food"

I just want to be sure that I understand the reasoning behind this correctly.

The object c is governed by the runtime setting Horse, but the parameter h, which is passed to the method is governed by the compile-time setting Mammal. So it doesn�t matter whether h is set to a run-time setting of Horse, Cattle or Mammal, its compile-time value of Mammal is used to find the matching method type.

Since the class Horse doesn't contain a "void eat(Mammal h)" method, and the class Cattle also doesn't contain a "void eat(Mammal h)" method, it finally passes to the Mammal class, which does contain the matching method and type.

If the object c was set to Cattle, then it would start looking at the Cattle level for the matching method and then start moving up towards it parent classes.

Is this correct?

( tags added)
[ January 11, 2005: Message edited by: Barry Gaunt ]
Harsh Singh
Greenhorn

Joined: Dec 08, 2004
Posts: 13
No.
First of all the method eat is not overridden but overloaded in this example.
Class cattle has two versions of eat: eat(Mammal) and eat(Cattle)
Class Horse has three versions of eat: eat(Mammal), eat(Cattle) and eat(Horse).

now for the line c.eat(h);
At the compile time it binds it to eat(Mammal) of the Cattle class.
At the runtime it runs the eat(Mammal) of the object Horse.

Hope that helps (& hope I am right ;-) )
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
I mostly agree with Harsh.

This version makes it clearer:


When overloading, the choice of method is decided at compile time based only on the lefthand side of the =. Since h is type Mammal, the chosen method for c.eat(h) must accept any Mammal object as its argument. Mammal.eat(Mammal m) will accept any Mammal object, but Cattle.eat(Cattle c) will only accept Cattle objects.

Horse.eat(Horse h) is not even considered, since c.eat(h) can only call methods known to class Cattle.

This question fooled me too because while c is type Cattle, h is type Mammal. Something to watch for.


Mike Gershman
SCJP 1.4, SCWCD in process
Bill Nelsen
Greenhorn

Joined: Aug 11, 2004
Posts: 27
Mike, you lost me on this line:

Horse.eat(Horse h) is not even considered, since c.eat(h) can only call methods known to class Cattle.

According to Harsh Singh:
now for the line c.eat(h);
At the compile time it binds it to eat(Mammal) of the Cattle class.
At the runtime it runs the eat(Mammal) of the object Horse.

So we are concerned with the runtime value of c (Horse) and the compile time value of its argument h (Mammal).

Run the following code:


class Mammal {
void eat(Mammal m) {
System.out.println("Mammal eats food");
}
}

class Cattle extends Mammal {
void eat(Cattle c) {
System.out.println("Cattle eats food");
}
}

class Horse extends Cattle {
void eat(Horse h) {
System.out.println("Horse eats food");
}
void eat(Mammal h) {
System.out.println("Horse Mammal eats food");
}
}

public class Test {
public static void main(String[] args) {
Mammal h = null;
Cattle c = new Horse();
c.eat(h);
}
}

prints "Horse Mammal eats food"
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
I said I mostly agreed with Harsh.

c.eat(h);

The runtime value of h has no role in method selection. The runtime value of c is only relevant for method overriding, which is not involved here.

c.eat(h), where c is type Cattle and h is type Mammal, can only call a method whose signature is known in class Cattle. The method signature "eat(Horse)" is not visible in class Cattle so it can't be invoked on a reference of type Cattle.

javac must choose between signatures "eat(Mammal)" and "eat(Cattle)". But "eat(Cattle)" can not handle an argument of type Mammal. Even if this time h refers to a Horse object, which is also a Cattle object, next time h may refer to a pure Mammal object, which is not a Cattle object.

So javac must choose the signature "eat(Horse)". If, at run time, c referred to an object with overridden "eat(Mammal)" methods, there would be a final choice made at run time. But that is not the case here.

Perhaps this third version of the program will illustrate the rule better. Here I changed the type of h from Mammal to Horse. javac still can't call "eat(Horse)" but it can now call "eat(Cattle)" because it knows that the argument will be of class Horse, which is also a Cattle. While "eat(Mammal)" would also work here, javac will call the more specific of two methods, the one that handles fewer possible argument types, if there is a choice at compile time.


Output: Cattle eats food.
Jay Pawar
Ranch Hand

Joined: Aug 27, 2004
Posts: 411
John,
There is an excellent sample chapter by Dan Chisholm which deals with overriding and overloading fundamentals. here is the link . Nice chapter with lot of brain-teasing questions.
Trust me, if you solve this questions correctly, you can handle any overloading, overriding questions in exam.

Hope this helps you...
[ January 11, 2005: Message edited by: Jay Pawar ]

Cheers,<br />Jay<br /> <br />(SCJP 1.4)<br />Heights of great men were not achieved in one day, they were toiling day and night while their companions slept.
Bill Nelsen
Greenhorn

Joined: Aug 11, 2004
Posts: 27
Thanks for your very informative reply, Mike.

I think that I understand things now. The counter case that I presented earlier involved the overriding of methods, in addition to the overloading of methods, so it was an entirely different situtation.

This was a very good problem for me, because it clearly illuminated several subtle areas in Java for me.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: inheritance confusion