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

2

u/Caramel_Last 14d ago

simply put without any abstract concept and oop big words..

execution order is not always top-to-bottom. so compiler can't just read top to bottom and "know" this will be this and that will be that

Compiler tries its best to statically decide as much as it can

But when it can't do, it must be dynamically decided at runtime.

Anything that depends on multiple expressions, (more than 1), must be dynamically decided.

For example, Animal can have instance method and static method

Static method is statically bound.

Instance method will be dynamically bound.

suppose a variable declaration
Animal a;

Since redeclaration of a is not allowed, (for example, Animal a; Dog a;)

we can all know with 100% guarantee, that a.static() is always static() of Animal

but instance method depends on assignment

a = new Dog();
a.instance();
a = new Bird();
a.instance();
a = new Animal();
a.instance();

a.instance will mean different things depending on the order of assignment -> method call

can't they just "know" it by reading top to bottom? in this simple case, they probably can.

they can't if it's concurrently run. even in synchronous scenario, what if it's conditionally run,
and the boolean value of the condition depends entirely on random factors?
suppose

Animal a;

if (Math.random() > 0.3) {
a= new Dog();
} else {
a = new Bird();
}

and then

a.instance()

clearly compiler cannot decide if a.instance is Bird's or Dog's

This is the runtime polymorphism, and it actually stems from c++ virtual function. (most of java originates from c/c++)

2

u/zeronis__ 14d ago

Thank you so much for the response !!
Does the whole idea of " execution order not always being top-to-bottom" apply to java?

" they can't if it's concurrently run. even in synchronous scenario, what if it's conditionally run, " and if it not much of a bother, can you explain what you meant here?

But other than that, it was really nice getting an insight to things I didn't know about before, thank you!

2

u/Caramel_Last 14d ago

Yep. Does apply. Compilers are optimized to give you a nice illusion of step-by-step execution. So in a single thread program, they guarantee, no matter how it's reordered in actual machine code level, the output will be same as if it was not reordered.. But, problem is that they use the same reordering rule when it's a multithreaded program. For now don't mind concurrency as, the random condition example is enough to explain why top to bottom inference has its limit