Question

Suppose we have the following Java interface:

// Java
public interface Foo {
    <T> T bar(Class<T> c);
}

How should I extend it in Scala? Writing

// Scala
class FooString extends Foo {
  override def bar(c: Class[String]): String = "hello, world";
}

will cause the compiler to throw "class FooString needs to be abstract, since method bar in trait Foo of type [T](Class[T])T is not defined."

Thanks in advance!

Update: The ugly truth is: I've misunderstood generics in Java.

In any case, the solutions to my woes are shown in both Nicolas' and Walter's answers, although I prefer Walter's answer better 'cos it's less verbose.

Was it helpful?

Solution

This works:

class FooString extends Foo {
  def bar[String](c: Class[String]): String = "hello world".asInstanceOf[String]
}

val fs = new FooString
println(fs.bar(classOf[String]))

Edited:

The comments from @Eastsun is correct. Since bar is a generic method with type parameter T, the implementation of bar in Scala has to be a generic method as well. I think the right way to implement Foo in Scala is the following:

class FooString extends Foo {
  def bar[T](c: Class[T]): T = c.newInstance.asInstanceOf[T] // c gotta have a default constructor
}

val fs = new FooString
println(fs.bar(classOf[String]).getClass) // prints "class java.lang.String"
println(fs.bar(classOf[java.util.Date]).getClass) // prints "class java.util.Date"

OTHER TIPS

It does not work because you do not implements the interface properly. The siganture of your method n scala must be:

def bar[T](c:Class[T]):T

You can fix the behaviour for String only if you want ton implements Foo.

Third try, according to our discussion:

def bar[T](c:Class[T]):T = {
  // Some stuff
  val o:Any = myUntypedFunction(env)
  c.cast(o)
}

According to the context the myUntypedFunction will create an object, and then you use the class parameter to cast your result and obtain a T object. Once again: this behavior is the same in java and in scala.

You may change like this:

public interface Foo<T> {
    T bar(Class<T> c);
}

class FooString extends Foo[String] {
    override def bar(c: Class[String]): String = "hello, world";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top