• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

a strange question about polymorphism

 
Teng Sun
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
please look at the following code first...

public class Animal {

public Animal() {}

private final void run() {
System.out.println("This is a private final method in Animal!");
}

public static void eat() {
System.out.println("Animal must eat!");
}

public static void main(String[] args) {
Animal animal = new Cat();
animal.run();
animal.eat();
}
}

class Cat extends Animal {

public Cat() {}

public static void eat() {
System.out.println("Cats like eating fish!");
}
}

In the main method of Animal, Animal animal = new Cat(); the animal variable refers to a Cat object in fact, so it should execute the method of Cat. But the Cat is the subclass of Animal, and it could neither extends the private and final methods nor see them. And to my surprise, the output is:
This is a private final method in Animal!
Animal must eat!
Besides, the static method eat in Cat must be a redefining method of Animal, not override i think.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Welcome to JavaRanch!
You haven't really told us what your question about this is. Code in the Animal class calls a private Animal method, and calls a static Animal method using a reference of type Animal. Nothing here is surprising to me. Tell me what part is surprising to you?

Maybe you expected the eat() method to be polymorphic, but in fact, static methods never are. The compiler chooses what static method will be invoked, not the runtime system. The compiler looks only at the compile-time type of the variable "animal", and doesn't know or care that animal points to a Cat.
 
Teng Sun
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, i'm a new comer here.
Animal animal = new Cat();
The animal refers to a cat object in fact, and it should execute the cat's method at runtime, but the cat doesn't have a run() method. So i feel a little confusion...
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because Cat is a subclass of Animal, the method Animal.run() is also available as Cat.run().
 
Teng Sun
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Although the cat is a subclass of animal, but it doesn't extends the animal's private final void run() method, how can it execute the run() method?
Besides, I send a e-mail to you, is it ejfried@javaranch.com? Waiting for your reply, thanks... And my e-mail: ebusiness022@yahoo.com.cn
 
Peixiao Lin
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In this case, once you instantiate cat class, cat constructor will also create animal instance because cat extends animal. So you can use an animal reference to access run() method though it refer to cat object actually. About eat(), cat override it. So the output is cat version. I don't know if this can answer your question.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
About eat(), cat override it. So the output is cat version.


Actually, you get the Animal version of eat()

When you use a reference variable to access a static method, the compiler just converts the reference type into its class name. So animal.eat() becomes Animal.eat() and the actual object referenced by animal is irrelevant. In fact, animal.eat() would work just the same if animal==null
 
Atul Chandran
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A reference of Animal type can call only the methods that are declared in the class Animal. The version of the method called is deffered till the runtime as the compiler is not sure what object the reference will refer. But in this case on seeing the keywords final or private the compiler can assume that there is only one version for this method and bind it at compile time.I think that's why the run() of Animal class gets called.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic