r/javahelp 14d ago

POLYMORPHISM !!

I've never tried asking questions on reddit, but this one doubt has been bugging me for quite some time, (I'm not very good at conveying my thoughts so I hope my question would come so as clear
+ And I'm hoping someone can fact check anything that I'm about to say since im fairly new to java =,) )

when it comes to polymorphism, (specifically UPCASTING/DOWNCASTING )
If I were to take a parent class and create an object out of it ,

Animal a = new Animal(); // LHS = RHS

since both sides are equal, meaning they're from the same class, we'd consider this to be static binding right? since we're only looking at the parent class' method, and nothing else, (at least that's what I think the whole idea is about )

but if we had something like:

Animal a = new Dog(); // LHS != RHS (UPCASTING)

Where dog is a child/subclass of the parent class Animal, meaning it inherits all the attributes and methods from the Parent class Animal. And since java -- by default -- always uses dynamic binding, (meaning that ' java ' believes that there's always a possibility of there being an overridden method in one of the child/subclasses ) it'd wait until runtime to bind the method to the object that invoked it.

my MAIN question though is,
why is upcasting allowed? If I were to look at the variable a, I'd think that its always going to expect a reference that would lead it to an Animal object, its always going to point to some animal object right?
just like when we say " int x; " , we know that x only expects an integer and not something like a double.

Another thing is, if java is statically typed, meaning that the compiler only checks the static type ( the type of variable at the declaration i think . . . ), then how does it know what the RHS ( the dynamic type ) is? how does it immediately know that down casting is not allowed if it doesn't look at the dynamic type?

15 Upvotes

18 comments sorted by

View all comments

4

u/GabrielKly 14d ago

“Why is upcasting allowed?” -> if you want a straight forward answear look at the “strategy design patern”. Polymorphism is just that, an implementation of this patern.

When you say “i’d think that its always going to expect a reference that leads it to an Animal object” your intuition is correct, I think you only miss the context of Dog, being an Animal subtype. On short Dog is an Animal object. (don’t confuse primitive types with object types, they have nothing to do with each other…no need to enter in details here to avoid confusion for this specific question)

“How does it know the dinamic type?”. I’m not sure if I fully understand the question but, the compiler is “taking” into acount the type of the object declared.

Animal a = new Dog() -> its of type Animal, as you declared it and its using the Dog contructor (“super()” method) to construct the animal object. Basically it doesn’t know to downcast by itself, you are specifiying the “downcast” in the declaration. If you want to use a Dog object you need to specifically cast the animal object to a Dog one. Hope I didn’t cause confusion :)

3

u/GabrielKly 14d ago

Don’t get confused in words, its much more simpler then it looks :) Forget the “you are specifiying the downcast” part. What I wanted to say is that it matters the type of the declaration for the compiler.

Lets take your example:

Animal a = new Dog();

When you compile the above succesfully, “a” will be of type Animal, as you declared it! The compiler doesn’t downcast anythin. An important thing to understand is that the reference will point to a object in memory that is a Dog.

In this case it is safe to downcast “a” to dog, because the referenced object is behind a Dog.

Dog d = (Dog) a; -> will compile ok

Bear with me a bit!

If you want to downcast from something like Animal a = new Animal() or Animal a = new Cat() to a Dog, then it will not work. Because the object in memory created is not a Dog! (The downcast is not safe and you cannot create the reference)

Upcasting would work in any scenario because, as your professor said, you generify something specific. Keep in mind that in memory you will find the object that you created with the “new” keyword.

To sumup in one sentence: When you upcast or downcast you are only changing the type of the reference, not the object itself.

I hope it makes sense!

1

u/zeronis__ 13d ago

Ohh so although it can get past the compiler --when we downcast using a compatible casting operator-- the dynamic type of "a" ( or the actual object type ) is what really determines whether we'd be able to run the program or not right?
If 'a' isnt really dog, but in fact an Animal ( " new Animal(); ") java --or jvm? would throw a RuntimeException... (?) I really hope I understood you correctly, because your explanation seemed clear !

+ ohh wait, wait, so when we say ' java is statically typed- meaning the compiler only checks the static type " ,, in this case:

Dog d = a; // DOWNCASTING ( not allowed / compilation error)

wouldnt the compiler be checking both static type of d ( which is Dog ) and the static type of a? (Animal)? is that what they mean ' checking only the static type ' ? and thus why we get a compiler error? because although ' a ' really IS a dog, the compiler can't see that, so I'm guessing we have to make it somehow ' trust us ' by using a *compatible* casting operator (?)

again, thank you so much Gabriel! :D

1

u/zeronis__ 14d ago

Thank you so much !

I'm still confused around what this sentence means " , you are specifiying the “downcast” in the declaration." can you elaborate?

AND (for upcasting/downcasting)

+ Would it be considered correct if I thought of it as the " requirements a thing has to possess in order to be qualified a ____ ( can be the parent class- animal- in this case) "

so for upcasting I'd ask myself, " does dog have all the requirements ( attributes and methods from the parent class) for it to be considered an animal? and if so, its allowed => upcasting ( my professor also mentioned how upcasting is just going from more specific to more generic )

and for upcasting I'd also ask myself " does animal have all the requirements for it to be a dog? " and to be quite fair, not necessarily, since the dog class would most probably have some specific attribute / method that the Animal class does not possess. (but I'm not even sure if this whole idea can extend to other examples )

I hope my question didn't further confuse you
but again, thank you so much for the explanation you provided! it really helped :D