2014-04-24 50 views
1
class Foo(protected[this] val s: Iterator[String]) { 
    def apply(it: Iterator[String]): Foo = new Foo(it ++ s) 
} 

class Bar(s: Iterator[String]) extends Foo(s) { 

} 

問:我怎樣才能Bar.apply()返回一個new Bar,而不是一個new Foo?我不想重寫。斯卡拉:多形菊花鏈

+0

爲什麼不重寫? – maks

+0

我簡化了這個例子,還有更多的方法需要以相同的方式和很多擴展類來執行。 – flavian

+0

爲什麼不提取'新Foo'在單獨的方法,然後覆蓋它(而不是覆蓋'申請')?例如'protected def create(s:Iterator [String]):Foo = new Foo(s)'。你也可以使用反射(但它可能是你不想做的事情,不是嗎?) – tenshi

回答

3

您可以使用F限制多態性來獲取返回正確類型的apply。您還需要定義創建子類的實例的方法:

abstract class Foo[X](protected[this] val s: Iterator[String]) { 
    self: X => 
    def newSubclass(s: Iterator[String]): X 
    def apply(it: Iterator[String]): X = newSubclass(it ++ s) 
} 

class Bar(s: Iterator[String]) extends Foo[Bar](s) { 
    def newSubclass(s: Iterator[String]): Bar = new Bar(s) 
} 

Bar.apply將有Bar作爲它的返回類型,而不需要被重寫。

您可以在Twitter Scala school瞭解更多關於F界多態性的信息。

+0

我還以爲F-bound也想不出如何引用構造函數。在新的子類上的榮譽,我正在尋找Mjolnir來破解堅果。 – flavian

0

已瀏覽this文章。看來這是你想要的。迅速scetch出簡單的例子(在此實例中使用var的)

class A(var s: String) { 
    def apply(a: String): this.type = { 
    s = "A" + a 
    this 
    } 
} 

class B(var s: String) extends A(s) 

P.S:嘗試使用瓦爾斯但它是impposible調用在方法構造,其返回類型是this.type。也許你會找到解決方案))

+0

不,'this.type'不會做你想做的。 'this.type'不是指'this'所屬的類,而是一種方法來說明一個方法返回'this'。 'this.type'的唯一值是'this'。它主要用於結合路徑相關類型的流暢API。 – wingedsubmariner