2009-09-24 34 views
4

假设我们有以下的Java接口:如何在Scala中扩展包含泛型方法的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 ]没有定义(类[T])T法吧”。

在此先感谢!

更新: 丑陋的真相是:我错误地理解了Java中的泛型。

在任何情况下,我的困境的解决方案都显示在Nicolas和Walter的答案中,尽管我更喜欢Walter的答案,因为它不那么冗长。

+0

你终于明白了!很高兴你已经理解你对泛型的错误。 不客气。 – Nicolas 2009-09-30 15:01:56

回答

3

这工作:

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的意见是正确的。由于bar是类型参数为T的泛型方法,因此Scala中bar的实现也必须是一个通用方法。我认为在Scala中实现Foo的正确方法如下:

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

实际上,它并不像您期望的那样工作。 FooString#bar方法中的“String”不是java.lang.String类型,而是Foo中的类型参数“T”。 所以你可以写一些像fs.bar(classOf [Int])并编译OK,但运行时会出现异常。 – Eastsun 2009-09-24 16:38:40

1

你可以改变这样的:

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

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

实际上,Java接口是第三方API,所以我必须照原样使用它。 – shaolang 2009-09-25 01:01:12

+0

据我所知,没有办法用一种特殊的类型方法覆盖泛型方法。 – Eastsun 2009-09-25 08:38:03

6

它不起作用,因为您没有正确实现接口。你的方法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中这种行为是一样的。

+0

这是我的问题:我如何进行签名比赛? – shaolang 2009-09-25 08:29:26

+0

你不能。您尝试更改界面,这不是一个scala问题,它是一个编程问题。接口说:“接受任何类并返回这个类的结果”,你的实现说“接受任何字符串类并返回一个字符串”。 bar的实现必须使用cast(),newInstance或一个构造函数来从对象c构建一个T. – Nicolas 2009-09-25 08:42:07

+0

这只是一个人为的例子;我遇到的实际问题需要我实现一个包含参数化类型的Java接口,类似于我给出的示例。 如果没有办法做到这一点,即使这可能是一个边缘情况,那么它是一个scala问题,因为它不完全兼容Java。 – shaolang 2009-09-25 09:51:03