Win a copy of OCP Java SE 8 Programmer II Exam Study Guide this week in the OCP forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Polymorphism with subclass method calls, and collections  RSS feed

 
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, so if you want to call a method from a subclass using polymorphism, you use a cast.



What if you have a collection like a hashmap where it takes in a lot of different subclasses and returns the object reference back of a subclass (B, C, or D) and you shove it in a temp variable. Is there a way to detect which subclass it is, as if the user picks which one and the code doesn't inherently know, so you can use the methods you want with an if/else statement or something?...
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jack Moore Iii wrote:Okay, so if you want to call a method from a subclass using polymorphism, you use a cast.



No. No matter what type you declare on the LHS, and no matter what casting you do, if you call a non-static, non-public, non-final method (the only thing that's runtime polymorphic in Java), you will always get the "deepest" version of that method. There is no way to invoke Parent's version of a polymorphic method on a Child instance, other than from inside the Child calling super.method().

What if you have a collection like a hashmap where it takes in a lot of different subclasses and returns the object reference back of a subclass (B, C, or D) and you shove it in a temp variable. Is there a way to detect which subclass it is, as if the user picks which one and the code doesn't inherently know, so you can use the methods you want with an if/else statement or something?...



If you care which subclass it is, you're doing it wrong. If you have a Map<Foo>, and in that Map you have various subclasses of Foo, you should only care that they are all Foos, and therefore just call Foo methods (with no casting), knowing that the proper implementation will be called automatically.
 
Jack Moore Iii
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:

No. No matter what type you declare on the LHS, and no matter what casting you do, if you call a non-static, non-public, non-final method (the only thing that's runtime polymorphic in Java), you will always get the "deepest" version of that method. There is no way to invoke Parent's version of a polymorphic method on a Child instance, other than from inside the Child calling super.method().



Well, when I didn't cast it to B, it could not find the symbol of B's method. When I did, it found the method and worked. So is that expected?



If you care which subclass it is, you're doing it wrong. If you have a Map<Foo>, and in that Map you have various subclasses of Foo, you should only care that they are all Foos, and therefore just call Foo methods (with no casting), knowing that the proper implementation will be called automatically.



So, if you have a bunch of getBlah() methods that are different for each subclass, you shouldn't care which subclass you're going off of? I'm trying to return all the info on stuff with an abstract method, while still retaining the ability to call each and every individual variable that may be different from subclass to subclass. Is that not correct logic?...
 
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Well, when I didn't cast it to B, it could not find the symbol of B's method. When I did, it found the method and worked. So is that expected?



That is because it(the compiler ) simply checks the reference variable type. If it has that method, it will give you a green flag, else it shall complain. Does your class A have a bMethod()? I presume it doesn't.
 
Marshal
Posts: 58384
178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jeff Verdegan wrote: . . . non-static, non-public, non-final . . . .

non placet

I think by, “non‑public,” you meant, “non‑private”.
 
Jack Moore Iii
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote:
That is because it(the compiler ) simply checks the reference variable type. If it has that method, it will give you a green flag, else it shall complain. Does your class A have a bMethod()? I presume it doesn't.



No, the A class only has a general, return everything in a string method which is abstract and different for each subclass. B and the other classes have individual variables that differ from subclass to subclass and A has none of that...
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could you perhaps share your classes' source code(if it is not too long)? I might be able to grasp a better picture and answer you appropriately then.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Jeff Verdegan wrote: . . . non-static, non-public, non-final . . . .

non placet

I think by, “non‑public,” you meant, “non‑private”.



Oops, yes, of course. Thanks for the correction.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jack Moore Iii wrote:

Mansukhdeep Thind wrote:
That is because it(the compiler ) simply checks the reference variable type. If it has that method, it will give you a green flag, else it shall complain. Does your class A have a bMethod()? I presume it doesn't.



No, the A class only has a general, return everything in a string method which is abstract and different for each subclass. B and the other classes have individual variables that differ from subclass to subclass and A has none of that...





 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jack Moore Iii wrote:
So, if you have a bunch of getBlah() methods that are different for each subclass, you shouldn't care which subclass you're going off of?



Correct. That's the point of inheritance and runtime polymorhpism. All I care about is that I have a List, and that I can call add(), and later call iterator(), and I will get things back in the order I added them. I don't care whether it's a LinkedList or an ArrayList or some other implementation. If I do care, I shouldn't be treating them as the same parent type (List) and shouldn't be dealing with them all together.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!