I have a collection (or list or array list) in which I want to put both String values and double values. I decided to make it a collection of objects and using overloading ond polymorphism, but I did something wrong.
I run a little test:
public class OOP { void prova(Object o){ System.out.println("object"); } void prova(Integer i){ System.out.println("integer"); } void prova(String s){ System.out.println("string"); } void test(){ Object o = new String(" "); this.prova(o); // Prints 'object'!!! Why?!?!? } public static void main(String[] args) { OOP oop = new OOP(); oop.test(); // Prints 'object'!!! Why?!?!? } }
In the test seems like the argument type is decided at compile time and not at runtime. Why is that?
This question is related to:
Polymorphism vs Overriding vs Overloading
Try to describe polymorphism as easy as you can
EDIT:
Ok the method to be called is decided at compile time. Is there a workaround to avoid using the instanceof
operator?
The main difference between multiple dispatch and function overloading (esp. as implemented in C++/other OOP langs.) is that overloaded functions still generally have an implicit receiver of fixed type, which constrains method dispatch to only those variants defined for the receiver.
Multiple dispatch or multimethods is a feature of some programming languages in which a function or method can be dynamically dispatched based on the run-time (dynamic) type or, in the more general case, some other attribute of more than one of its arguments.
Java doesn't support double dispatch. Note that double dispatch is often confused with method overloading, which is not the same thing. Method overloading chooses the method to invoke based only on compile-time information, like the declaration type of the variable.
Introduction. Method overloading is a salient feature in Object-Oriented Programming (OOP). It lets you declare the same method multiple times with different argument lists.
This post seconds voo's answer, and gives details about/alternatives to late binding.
General JVMs only use single dispatch: the runtime type is only considered for the receiver object; for the method's parameters, the static type is considered. An efficient implementation with optimizations is quite easy using method tables (which are similar to C++'s virtual tables). You can find details e.g. in the HotSpot Wiki.
If you want multiple dispatch for your parameters, take a look at
this.resend(...)
instead of super(...)
to invoke the most-specific overridden method of the enclosing method;If you want to stick with Java, you can
Value dispatching:
class C { static final int INITIALIZED = 0; static final int RUNNING = 1; static final int STOPPED = 2; void m(int i) { // the default method } void m(int@@INITIALIZED i) { // handle the case when we're in the initialized `state' } void m(int@@RUNNING i) { // handle the case when we're in the running `state' } void m(int@@STOPPED i) { // handle the case when we're in the stopped `state' } }
What you want is double or more general multiple dispatch, something that is actually implemented in other languages (common lisp comes to mind)
Presumably the main reason java doesn't have it, is because it comes at a performance penalty because overload resolution has to be done at runtime and not compile time. The usual way around this is the visitor pattern - pretty ugly, but that's how it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With