假设我们有以下的Java接口:
// Java
public interface Foo {
<T> T bar(Class<T> c);
}
我应该如何在斯卡拉其扩展? 写作
// Scala
class FooString extends Foo {
override def bar(c: Class[String]): String = "hello, world";
}
将使编译抛出“类FooString需要是抽象的,因为在类型的性状的Foo [T方法bar ]
(类[T])没有被定义吨。”
提前致谢!
更新:丑陋的真相是:我在Java的泛型误解。
在任何情况下,我的困境的解决方案,显示在两个萨科和沃尔特的答案,但我更喜欢Walter的回答更好“因为它更简洁。
这工作:
class FooString extends Foo {
def bar[String](c: Class[String]): String = "hello world".asInstanceOf[String]
}
val fs = new FooString
println(fs.bar(classOf[String]))
编辑:
从@Eastsun的意见是正确的。 由于酒吧是类型参数T的通用方法,棒的Scala中实现必须是通用的方法为好。 我认为,在Scala中实现富的正确方法如下:
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"
这是行不通的,因为你没有正确实现接口。 你的方法N阶的siganture必须是:
def bar[T](c:Class[T]):T
只有当你想实现吨符您可以修复行为的字符串。
第三次尝试,根据我们的讨论:
def bar[T](c:Class[T]):T = {
// Some stuff
val o:Any = myUntypedFunction(env)
c.cast(o)
}
根据该上下文myUntypedFunction将创建一个对象,然后使用类参数来投你的结果,并获得一件T对象。 再次:这种行为是在Java和Scala中一样。
你可以改变这样的:
public interface Foo<T> {
T bar(Class<T> c);
}
class FooString extends Foo[String] {
override def bar(c: Class[String]): String = "hello, world";
}