Метод применения по умолчанию класса Case
Предполагая, что мы имеем следующий класс case:
case class CasePerson(firstName: String)
И мы также определяем для него объект-компаньон:
object CasePerson {
def apply() = new CasePerson( "XYZ" )
}
Обратите внимание, что в приведенном выше примере я явно определил объект-компаньон с помощью метода apply
, не определяя метод применения по умолчанию:
// This "default" apply has the same argument as the primary constructor of the case class
def apply(firstName : String) = new CasePerson(firstName)
Q: Итак, где применяется Scala этот "по умолчанию"? Я явно определил объект-компаньон здесь без применения по умолчанию, и компилятор все еще знает, как это выполнить:
val casePerson = CasePerson("PQR")
Как это работает?
Ответы
Ответ 1
Scala классы case - это синтаксический сахар. Когда вы создаете класс case, компилятор Scala создаст сопутствующий объект с помощью метода apply
и unapply
, который вы можете использовать, как если бы он просто существовал. Здесь - ссылка на более подробную информацию о классах case.
Ответ 2
Классы классов неявно сопровождаются сопутствующим объектом с apply()
, который имеет те же аргументы, что и основной конструктор класса case.
То есть:
case class CasePerson(firstName: String)
Будет сопровождаться
object CasePerson{
def apply(firstName: String) = new CasePerson(firstName)
}
Теперь, если вы также явно определяете объект-компаньон, вы можете думать об этом как о добавлении к неявно определенному.
Например, в вашем примере вы добавили один новый apply
к сопутствующему объекту:
object CasePerson{
def apply() = new CasePerson("XYZ")
}
Этот оператор, вы можете думать об этом, как будто он создает объединенный объект-компаньон:
object CasePerson{
def apply() = new CasePerson("XYZ") // the one manually added
def apply(firstName: String) = new CasePerson(firstName) // this one is automatically added
}
Теперь, если вы решите добавить свою собственную версию apply
, которая имеет те же аргументы, что и основной конструктор, это затмит поведение по умолчанию класса case.
object CasePerson{
def apply() = new CasePerson("XYZ")
def apply(s: String) = Seq(new CasePerson(s), new CasePerson(s)) // will replace the default factory for the case class
}
Теперь, если вы вызываете CasePerson("hi")
, он будет генерировать:
List(CasePerson("hi"), CasePerson("hi"))
Ответ 3
Вы также можете присвоить параметру класса firstName
значение по умолчанию. Таким образом, вы можете создать экземпляр с отсутствием параметра.
Пример:
case class CasePerson(firstName : String = "XYZ")
val person = CasePerson()