Каков вариант использования вторичных конструкторов в абстрактных классах?

Рассмотрим этот код:

abstract class Foo(val s: String) {
  def this(i: Int) = this("" + (i+2))
}

Насколько я понимаю, конструкторы не наследуются, а вторичные конструкторы нельзя вызывать из подклассов с super, как в Java.

Являются ли они просто бесполезным артефактом или есть какой-то разумный прецедент для этой конструкции?

Ответы

Ответ 1

scala> object Bar extends Foo(3)
defined module Bar

scala> Bar.s
res3: String = 5

Ответ 2

Основной конструктор подкласса должен вызывать один из конструкторов суперкласса, не обязательно первичный.

abstract class A(s: String) {
  def this(i: Int) = this(i.toString)
}
class B(i: Int) extends A(i)

Ответ 3

В дополнение к ответу @coubecczech вы также можете создавать экземпляры абстрактных классов (и признаков), если вы добавляете уточнение,

scala> :paste
// Entering paste mode (ctrl-D to finish)

abstract class Foo(val s: String) {
  def this(i: Int) = this("" + (i+2))
}

// Exiting paste mode, now interpreting.

defined class Foo

scala> val f = new Foo(23) {}
f: Foo = [email protected]

scala> f.s
res3: String = 25

Хотя я показываю пустое уточнение выше ( "{}" ), вы обычно предоставляете некоторые дополнительные определения, часто предоставляя реализации для абстрактных членов,

scala> abstract class Bar { def bar : Int }
defined trait Bar

scala> val b : Bar = new Bar { def bar = 23 }
b: Bar = [email protected]

scala> b.bar
res1: Int = 23