Scala: сопутствующие объекты из подклассов - PullRequest
0 голосов
/ 17 января 2019

Я хочу создать сопутствующий объект, который является подклассом параметризованного базового класса, а только фиксирует параметр базовых классов, то есть все методы наследуются от базового класса.

Один из способов сделать это - использовать черту:

class Foo(v: Int, printStream: PrintStream) {
  def print: Unit = printStream.println(v);
}

trait FooFactory {
  protected val printsTo: PrintStream

  def apply(v: Int) = new Foo(v, printsTo)
  def makeFoo(v: Int) = apply(v)
}

object Foo extends FooFactory {
  protected val printsTo: PrintStream = System.out
}

val foo = Foo(3)
foo.print
val f2 = Foo.makeFoo(2)
f2.print

Этот способ выглядит чище, но Intellij считает, что методы базового класса недоступны вне модуля компиляции (файл .scala, который определяет компаньон):

class Bar(v: Int, printStream: PrintStream) {
  def print: Unit = printStream.println(v);
}

class BarFactory(printsTo: PrintStream) {
  def apply(v: Int) = new Bar(v, printsTo)
  def makeBar(v: Int) = apply(v)
}

object Bar extends BarFactory(System.out) {}

val bar = Bar(3)
bar.print
val b2 = Bar.makeBar(2)
b2.print

Эффективно ли они эквивалентны (за исключением, конечно, смены имени Foo => Bar)? Один предпочтительнее?

Цель состоит в том, чтобы предоставить сопутствующему объекту PrintStream по умолчанию, позволяя при этом пользователям создавать другие фабрики, если им необходимо:

val BarLoggerFactory = new BarFactory(someLogPrintStream)
val bar3 = BarLoggerFactory.makeBar(3);
...