Implementing a Java interface method in Scala
My implementation of a getHandler
method, which is defined on a Java interface, has failed, and I don't know why. Here is the method signature:
<H extends EventHandler> H getHandler( Type<H> type, int index );
My implementation in Scala is:
def getHandler[H <: com.google.gwt.开发者_如何转开发event.shared.EventHandler]
(aType: Type[H], index: Int): H
= new com.google.gwt.event.shared.EventHandler() {}
...but the compiler gives me this message:
type mismatch;
found: java.lang.Object with com.google.gwt.event.shared.EventHandler
required: H
Where have I erred?
I think it's because your implementation doesn't uphold the contract of the interface. H
could be any subtype of EventHandler
, determined by the type of the aType
argument. But your implementation always returns the same anonymous subtype of EventHandler
, regardless of what is passed as the aType
argument.
I don't know what a correct implementation would be, but I can't see how this could be implemented without somehow making use of the aType
parameter.
Adding to Lachlan's answer I'd like to point out, that simply casting the return type to the expected type may have desastrous effects.
Consider the following implementation where I have used a named class instead of the anonymous inner class from the question:
class MyHandlerA extends EventHandler
class MyHandlerB extends EventHandler
object BadImplementation extends I {
def getHandler[H <: EventHandler](typ : Type[H], index: Int) = {
(new MyHandlerA).asInstanceOf[H] // BAD: This asInstanceOf is a lie!
}
}
The following line will cause a ClassCastException
without warning.
val b: MyHandlerB = BadImplementation.getHandler(new Type[MyHandlerB] {} , 0)
So in addition to the cast an implementation will have to ensure that the returned handler is actually assignable to H or return null
or throw an exception.
I think this may make it compile:
def getHandler[H <: com.google.gwt.event.shared.EventHandler]
(aType: Type[H], index: Int): H = {
val h = new com.google.gwt.event.shared.EventHandler() {}
h.asInstanceOf[H]
}
It's expecting an H
. As Lachlan says, aType
probably is needed somewhere.
精彩评论