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