• 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
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

a strange question about polymorphism

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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 [email protected]? Waiting for your reply, thanks... And my e-mail: [email protected]
 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
This cake looks terrible, but it tastes great! Now take a bite out of this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic