Scala: возможно ли переопределить конструктор класса case по умолчанию?
Просто интересно, возможно ли это.
То, что я действительно хотел бы сделать, это проверить и, возможно, изменить один из аргументов, прежде чем он будет сохранен как val.
В качестве альтернативы я могу использовать перегрузку и сделать конструктор по умолчанию закрытым. В этом случае я также хотел бы сделать закрытым конструктор по умолчанию factory в сопутствующем объекте, как бы я это сделал?
Большое спасибо.
Адам
edit: хорошо, я понял, что создание конструктора по умолчанию private также делает конструктор по умолчанию factory закрытым, поэтому у меня есть решение, мне все же интересно узнать, является ли конструктор по умолчанию переопределяемым, хотя
Ответы
Ответ 1
Наличие конструкторов класса вторичного случая не приводит к тому, что компилятор создает дополнительные методы factory в компаньоне класса, поэтому для их создания вы не получите удобство CaseClaseName(«secondary constructor parameter list»>)
. Вам нужно будет использовать ключевое слово new
.
Лучше указать, какую логику вы описываете в альтернативных factory методах в сопутствующем объекте и придерживаетесь использования основного конструктора.
Ответ 2
У вас нет возможности изменить способ, которым конструктор по умолчанию сохраняет свои параметры (например, путем изменения параметров до того, как они будут сохранены как val
s), но у вас есть возможность выбросить исключение, если параметры неверны (это произойдет после сохранения параметров)
case class Foo(x:Int){
if (x<0) throw SomeException;
}
У вас также есть возможность реализовать дополнительные конструкторы, которые вызывают первый конструктор
case class Foo(x:Int){
def this(x:Int,y:Int) = this(x+y)
}
но они не получают методы factory.
Вы можете легко создать метод factory самостоятельно, добавив его к сопутствующему объекту
object Foo{
def apply(x:Int,y:Int) = new Foo(x,y)
}
Что-нибудь еще сложнее, и вам придется отказаться от класса case и реализовать его самостоятельно: apply
, unapply
, equals
и hashCode
. Программирование в Scala говорит о том, как сделать все это, давая хорошие формулы для equals
и hashCode
.
Ответ 3
Вы можете перегружать конструкторы. Это то же самое, что и в С++ или Java. Просто создайте другой конструктор.
class Foo( _input:Int ){
def this() = this( 0 )
}
Или вы можете видеть этот сообщение SO.
Ответ 4
Вы можете превратить обычный класс в псевдо-case-класс, написав собственные методы apply
(для factory) и unapply
(для соответствия шаблону) в объекте-компаньоне. Или вы можете просто написать метод с именем factory в объекте класса класса case.