Перегрузка конструктора Scala?

113

Как вы предоставляете перегруженные конструкторы в Scala?

Теги:

6 ответов

168
Лучший ответ

Стоит прямо упомянуть, что вспомогательные конструкторы в Scala должны либо называть основной конструктор (как в случае с landon9720), либо другой вспомогательный конструктор из того же класса, что и их первое действие. Они не могут просто вызвать конструктор суперкласса явно или неявно, как они могут в Java. Это гарантирует, что основной конструктор является единственной точкой входа в класс.

class Foo(x: Int, y: Int, z: String) {  
  // default y parameter to 0  
  def this(x: Int, z: String) = this(x, 0, z)   
  // default x & y parameters to 0
  // calls previous auxiliary constructor which calls the primary constructor  
  def this(z: String) = this(0, z);   
}
  • 0
    @Jon McAuliffe: плохой пример? Без второго и третьего конструкторов пользователь по-прежнему может вызывать new Foo(x=2,z=4) и new Foo(z=5) если вы измените свою первую строку на class Foo(x: Int = 0, y: Int = 0, z: String) {
  • 0
    Аргументы Named / Default не поступали до Scala 2.8.
Показать ещё 1 комментарий
27
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }
  • 3
    Подожди ... Зачем ты отправил вопрос, если уже знаешь ответ?
  • 15
    1. Я хотел посмотреть, сможет ли SO ответить на вопрос быстрее, чем смогу его найти (нет, не может). 2. Я хотел внести немного чего-нибудь
Показать ещё 3 комментария
13

Как и в случае с Scala 2.8.0, вы также можете иметь значения по умолчанию для параметров конструктора и метода. Как этот

scala> class Foo(x:Int, y:Int = 0, z:Int=0) {                           
     | override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
     | }
defined class Foo

scala> new Foo(1, 2, 3)                                                    
res0: Foo = Foo(1, 2, 3)

scala> new Foo(4)                                                          
res1: Foo = Foo(4, 0, 0)

Параметры со значениями по умолчанию должны появляться после тех, у которых нет значений по умолчанию в списке параметров.

  • 3
    Это не работает для нетривиальных значений по умолчанию. поэтому class Foo(val x:Int, y:Int=2*x) не работает.
  • 0
    @ Йорген Лундберг: вы написали, что параметры со значениями по умолчанию должны идти после тех, у которых нет значений по умолчанию в списке параметров. Это неправильно, new Foo(x=2,z=4) выведет Foo(2,0,4) .
Показать ещё 2 комментария
8

Когда я смотрел на свой код, я вдруг понял, что я сделал перегрузку конструктора. Затем я вспомнил этот вопрос и вернулся, чтобы дать еще один ответ:

В Scala вы не можете перегружать конструкторы, но вы можете сделать это с помощью функций.

Кроме того, многие предпочитают делать apply функцию сопутствующего объекта a factory для соответствующего класса.

Выполняя этот класс абстрактно и перегружая функцию apply для реализации-создания этого класса, у вас есть перегруженный "конструктор":

abstract class Expectation[T] extends BooleanStatement {
    val expected: Seq[T]
    …
}

object Expectation {
    def apply[T](expd:     T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
    def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected =      expd }

    def main(args: Array[String]): Unit = {
        val expectTrueness = Expectation(true)
        …
    }
}

Обратите внимание, что я явно определяю каждый apply, чтобы возвращать Expectation[T], иначе он вернул бы утиный Expectation[T]{val expected: List[T]}.

1

Я думал, может быть Scala Конструкторы (2008-11-11) может добавить дополнительную информацию.

0

Попробуйте это

class A(x: Int, y: Int) {
  def this(x: Int) = this(x, x)
  def this() = this(1)
  override def toString() = "x=" + x + " y=" + y
  class B(a: Int, b: Int, c: String) {
    def this(str: String) = this(x, y, str)
    override def toString() =
      "x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
  }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню