Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloaded methods priority

I have a base-class called Element. Some other classes (like Label and Image) both extend this class.

I now have a dispatching class having the following methods:

public class Dispatcher {
    public static AbstractPropertyEditor<Label> createEditor(Label e) {
    ...
    }

    public static AbstractPropertyEditor<Element> createEditor(Element e) {
    ...
    }
}

If now I have an instance of Label (which extends Element) and I want to pass it to createEditor(), why is the most generic method (the second one) called? Wouldn't it be normal that the most specific method (createEditor(Label e)) is called?

I absolutely need the method with the Element-param in order to "catch" all those classes that a) implement Element but do not have their own specific method in this dispatching class..

I'm using Java 6, how to "fix" this?

Edit: Okay, I have to admit it's not at all about generics. But that's where I encountered it the first time.

thanks and regards

like image 436
Atmocreations Avatar asked Feb 14 '10 21:02

Atmocreations


2 Answers

Why don't you:

  • make Element abstract class that provides a default createEditor() implementation
  • make Label override the createEditor().

Thus you won't need the static utilities and will achieve your goal.

If you need Element to be an interface, then:

  • define createEditor() as methods of Element
  • define a EditorFactory interface
  • provide DefaultEditorFactory and ListEditorFactory
  • use the appropriate factories in the implementors of Element:

    public Editor createEditor() {
         editorFactory.createEditor(this);
    }
    

where the concrete EditorFactory is instantiated either during initialization or via some sort of dependecy-injection.


As per your concrete question - it depends on what type you have compiled there. If you call createEditor(obj) it will depend whether it's Element obj = .. or Label obj = ..

like image 69
Bozho Avatar answered Oct 02 '22 11:10

Bozho


This really has little to do with generics, and everything to do with method overloading. In Java, the method signature called is determined at compile time, not at runtime, so you have to check and cast at runtime.

So replace this:

 Element label = getLabel();
 AbstractPropertyEditor<?> editor = createEditor(label);   

With this:

 Element label = getLabel();
 AbtractPropertyEditor<?> editor;
 if(label instanceof Label) {
      editor = createEditor((Label) label);
 } else {
      editor = createEditor(label);
 }

The other (more standard/better) way to fix this is to have the createEditor(Element) method check the type and call with a cast the correct overloaded method for subtypes. However, you will have an issue with your return parameters if you do that on the methods as declared.

like image 29
Yishai Avatar answered Oct 02 '22 09:10

Yishai