简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM