I am suprised that it compiles for the following reasons.
1. A class can't inherit private instance variables so the Dog class should not have a version of the eat() method, it does however inherit the callEat() method from Animal because that has public access.
2. Although the a1 is of type Animal, the actual method called will be decided at runtime based on the actual type of the object (which is a Dog). So the callEat() method should be the Dog's version inherited from the Animal class.
3. I thought what would happen next is that the method would try and find an eat() method in the Dog object, fail to find it because it hasn't been inherited, and so give some sort of "method eat() not found" error. Instead it actually compiles and runs fine.
I'm confused as to how the eat method can be called when there is no eat method in the Dog object.
Joe Lemmer wrote:
3. I thought what would happen next is that the method would try and find an eat() method in the Dog object, fail to find it because it hasn't been inherited,
you are calling callEat which is not a private method , but it calls a private method of eat which is in the same class. so when you call eat method on Dog it gets the Animal callEat method(this can access the eat method since both methods are in a same class). it is fine.
|BSc in Electronic Eng| |SCJP 6.0 91%| |SCWCD 5 92%|
Joined: Oct 24, 2008
Thanks for your replies and the link. I still don't understand what is happening though.
What I am visualising is that the 'a1' variable which is of type Animal is assigned a Dog object.
When this Dog object was being constructed, it inherited a method from the Animal class called callEat(), but that is now a Dog object method in the actual live Dog object.
Whereas because the eat() method was marked private in the Animal class, the Dog object cannot inherit it, so it does not have a copy in the live Dog object.
My understanding was that at runtime, the JVM would see that the actual object assigned to the Animal a1 variable was an instanceof Dog and so it would use the Dog object's callEat() method which would then try and call the Dog object's callEat() method and run into trouble because the Dog object has been unable to inherit that method.
...Actually I think I am beginning to understand that this applies only when overriding is taking place. So when I modify my code so that the callEat() method is overridden in the Dog object, like so:
I now get the "can't find symbol... eat()" compiletime error that I've been expecting.
So, if I'm right, then that means that when a class extends another class but doesn't override any of the inherited methods, then the copies of the methods it inherits are considered to be of the type of the superclass. So in my original example where the callEat() method wasn't overridden in the Dog class, the Dog object inherits the callEat() method from the Animal class and when the compiler checks it sees that the callEat() method is of type Animal, so it will be able to access Animal's private eat() method.