4

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.

1
  • You finally get it! Glad you've understood your mistake on generics. You're welcome. Commented Sep 30, 2009 at 15:01

3 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

11 Comments

That's my question: how do I make the signature match?
You cannot. You try to change the interface, it's not a scala issue, it's a programming one. the interface says: "Accept any class and return a resut of this class", your implementation says "Accept any String class and returns a string". An implementation of bar must certainly use cast(), newInstance or a constructor to build a T from the object c.
This is only a contrived example; the actual problem I'm facing requires me to implement a Java interface which contains parametrized type in the method, something similar to the example I've given. If there is no way to achieve this, even though this may be an edge case, then it is a scala issue because it is not fully compatible with Java.
I don't think that it is a scala issue. You can't do this in Java any way.
@shaolang: If you think it's a scala problem, could you please give us the valid java equivalent code for your FooString class? I still believe you have miss the point of the generics declaration in the bar function.
|
3

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"

1 Comment

Actually, it doesn't works as you expected. The "String" in method FooString#bar is not the type java.lang.String but a type parameter as "T" in Foo. So you may write something like fs.bar(classOf[Int]) and compile OK,but run with an exception.
1

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";
}

2 Comments

Actually, the Java interface is a third party API, so I have to use it as it is.
As far as I know, there is no way to override a generic method with a special type method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.