• Post Reply Bookmark Topic Watch Topic
  • New Topic

Interface "gotcha"  RSS feed

 
Malcolm Storey
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's an Interface "gotcha" that I don't think I've read about.

If you have two method calls with the same name where the second has an argument
that is a subclass of the one in the first method, the one used at runtime will depend on
the class of the object passed as the parameter. Standard Java.

If you now put the call with the superclass argument into an interface, the subclass method will never be used.

Example:



With the Interface it'll print "Interface Method". Without it, it'll print "Subclass Method".

(At least, that's how it works in Eclipse).

It's not nice that adding an Interface (really just a clean way of avoiding lots of casts)
can change the execution of a program.

Surely it should either honour both methods or flag the redundant one as an error?
 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Everything works as expected, the subclass method should be called. It's not possible to reproduce your scenario because the code you have is not valid. Please post an SSCCE.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Malcolm Storey wrote:
With the Interface it'll print "Interface Method". Without it, it'll print "Subclass Method".


Can you show us the "with the interface" example? As what you showed doesn't use the interface.


As for your example, when more than one method (along with the signature) match, the compiler has to figure out which one to use. It has a few ways to do this, and one of those ways is to choose the "most specific" method (which is the one that takes the subclass object).

Henry
 
Malcolm Storey
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I didn't get the example code quite right, and it won't let me edit the original question.


 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We want to be able to paste the code in our text editor, save it to a file without editing anything, and run javac.exe on it. Please google for SSCCE.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Agreed with Stephan. The new code doesn't add anything here to clear the confusion.

Henry
 
Malcolm Storey
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, third try:

 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

In your first example, you passed a SubclassOfInterfaceArg instance to the interfaceMethod() of the Whatever class. This can match the signature of both methods, and hence, the compiler will choose the most specific method, which is the one that takes the Subclass argument.

In you third example, you passed an InterfaceArg instance to the interfaceMethod() of the Whatever class. This can only match one of the two overloaded methods. And hence, it calls the one that matches, which is the one that takes the InterfaceArg argument.

Henry
 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Malcolm, this is still not an SSCCE.

Give us something that we can copy, paste and compile.


Henry has found an answer to your problem.
 
Stefan Evans
Bartender
Posts: 1837
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a prime example of Early binding.
Decisions as to which overloaded method will be called happens at compile time
Late binding (which polymorphic version of the method gets called) happens at runtime.

Note that the interface only declares one method, while the implementation of the interface 'overloads' the interface with a new declaration.
That version of the method is only visible to a variable declared as type Whatever.

 
Stefan Evans
Bartender
Posts: 1837
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, and here is an SCCE demonstrating the 'issue' as I understand it.



The results of running (with the difference highlighted) are:

Calling method that takes parent class with Parent Class Object
Calling method that takes parent class with Child Class Object
Calling method that takes parent class with Child Class Object

Calling method that takes parent class with Parent Class Object
Calling method that takes child class with Child Class Object
Calling method that takes parent class with Child Class Object
 
Malcolm Storey
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks guys, that makes sense now. I was concentrating too much on the view from the class/method and ignoring its calling context.
 
Ashwin Rao
Ranch Hand
Posts: 89
C++ Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stefan Evans wrote:Oh, and here is an SCCE demonstrating the 'issue' as I understand it.




How does your program work? It has no main method! :|
I haven't seen code like yours before.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ashwin, Stefan's code is written as a JUnit test.

JUnit is a very widely used tool for writing unit tests.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ashwin Rao wrote:
How does your program work? It has no main method! :|
I haven't seen code like yours before.

JUnit or something like it needs to be in every programmer's arsenal of development tools. In fact, you should have a test class for every production class you write. I will go even further and say that you should write some test code before you write any line of production code. If you haven't used JUnit yet, you'd be well advised to start learning how to use it as soon as possible.

[RANT ]
I find it mind-boggling that with all the information available online and in print, there seems to be a disproportionately large number professional developers out there who don't know how to unit test versus those who do. And based on the kind of questions we see in these forums and the dearth of activity in the Testing forum, I just can't fathom why it seems that new programmers aren't being taught about unit testing at all!

One of the first things you are taught when you learn how to drive is how to use your seatbelt. Then you're taught a bunch of other things, mostly related to operating the vehicle safely. In programming, learning how to use a unit test harness like JUnit is like learning how to be a safe driver. I think we really need a catchy slogan like "Click it or ticket!" in our field. "Test it or debug it!" just doesn't have that same kind of ring to it though... I don't know maybe it will grow on me.
[/RANT]
 
Stefan Evans
Bartender
Posts: 1837
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'll admit to being lazy.
I could have put a public static void main method, instantiated the object and called the testing method explicitly.
In fact I used to do that quite a lot when I wanted to test bits and pieces. But that ended up with a significant amount of "boilerplate" code - particularly if I then put in a try/catch to print exceptions.

Putting the @Test annotation on the method is easier, and gives you the functionality to test throwaway code without needing excessive amounts of boilerplate.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!