Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Method Overloading Called with an Interface

I'm sure this is elementary, but I am stumped. The example is grossly over-simplified but boils down to the following. I have some overloaded methods in a class like so:

public void build(MyImplOneOfAnInterface item);
public void build(MyImplTwoOfAnInterface item);

I then have another method that does the following:

public void buildIt(MyInterface item) {
     build(item);
}

When I attempt to compile, I get the following error:

cannot find symbol

This is because the JVM cannot determine the implementation of the interface at compile time so that it knows which overloaded method to call.

How can this be decided at runtime? It seems like the JVM ought to be able to figure this out.

PS: I don't want to define a method that takes the interface as the argument and then does a bunch of if/else statements using instanceof operators.

like image 959
Josh Harness Avatar asked Jul 18 '11 15:07

Josh Harness


People also ask

Can we do method overloading in interface in Java?

Yes, you can have overloaded methods (methods with the same name different parameters) in an interface. You can implement this interface and achieve method overloading through its methods.

Can you call a method from an interface in Java?

In order to call an interface method from a java program, the program must instantiate the interface implementation program. A method can then be called using the implementation object.

Can an interface contain method bodies?

Interfaces are declared using the interface keyword, and may only contain method signature and constant declarations (variable declarations that are declared to be both static and final ). All methods of an Interface do not contain implementation (method bodies) as of all versions below Java 8.


3 Answers

You could use double dispatch. Have a MyInterface.build, which is then overloaded in your implementation classes to call the relevant method. e.g.:

interface MyInterface {
    void build(Thingy t);
}

class MyImplOneOfAnInterface implements MyInterface {
    void build(Thingy t) { t.build(this); }
}

...

void buildIt(MyInterface item) {
    item.build(this);
}
like image 138
Oliver Charlesworth Avatar answered Nov 02 '22 09:11

Oliver Charlesworth


Place the build() logic within the implementation. . So instead of build(item) call item.build().

Or take a look at the visitor pattern, where you can do item.build(builder) instead of builder.build(item)

like image 32
Bozho Avatar answered Nov 02 '22 07:11

Bozho


You are looking the inheritance at the wrong side.

MyImplOne... and MyImplTwo are both implementations of your interface. But if you call build(item), it will expect to find

public void build(MyInterface item):

else, it may find that you pass an object that implements your interface but is neither from class MyImplOne or MyImplTwo.

Like as defining a method

public void print(Vector vector);

and hoping that the compiler can resolve

print(new Object());
like image 1
SJuan76 Avatar answered Nov 02 '22 07:11

SJuan76