简体   繁体   中英

Scala: Polymorphic daisy chaining

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) {

}

Question: How can I get Bar.apply() to return a new Bar instead of a new Foo ? I don't want to override.

You can use F-bounded polymorphism to get an apply that returns the proper type. You also need to define a method that creates an instance of the subclass:

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 will have Bar as its return type, without needing to be overriden.

You can read more about F-bounded polymorphism at the Twitter Scala school .

Have looked through this article. Seems it's what you want. Quickly scetch out simple example(using var 's in this example)

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

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

PS: Tried to use vals but it is impposible to call constructor in method which return type is this.type . Maybe you'll find the solution))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM