假设一个人想要构建一个新颖的泛型类,Novel[A]
. 这个类将包含许多有用的方法——也许它是一种集合——因此你想继承它。但是您希望方法返回子类的类型,而不是原始类型。在 Scala 2.8 中,为了使该类的方法返回相关子类而不是原始子类,需要做的最少工作量是多少?例如,
class Novel[A] /* What goes here? */ {
/* Must you have stuff here? */
def reverse/* What goes here instead of :Novel[A]? */ = //...
def revrev/*?*/ = reverse.reverse
}
class ShortStory[A] extends Novel[A] /* What goes here? */ {
override def reverse: /*?*/ = //...
}
val ss = new ShortStory[String]
val ss2 = ss.revrev // Type had better be ShortStory[String], not Novel[String]
如果你想Novel
协变,这个最小量会改变吗?
(除其他外,2.8 集合做到了这一点,但它们也以更花哨(和有用)的方式使用返回类型——问题是如果一个人只想要这个子类型-总是-返回-子类型,那么可以摆脱多少框架特征。)
编辑:假设在上面的代码中reverse
进行了复制。如果进行就地修改然后返回自己,则可以使用this.type
,但这不起作用,因为副本不是this
。
Arjan 链接到另一个建议以下解决方案的问题:
def reverse: this.type = {
/*creation of new object*/.asInstanceOf[this.type]
}
这基本上取决于类型系统以获得我们想要的东西。但这并不是一个真正的解决方案,因为既然我们对类型系统撒了谎,编译器就无法帮助我们确保当我们认为我们确实得到了ShortStory
回报时。(例如,我们不必reverse
在上面的示例中重写以使编译器满意,但我们的类型不会是我们想要的。)