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.