Scala: возможно ли переопределить конструктор класса дел по умолчанию? - PullRequest
19 голосов
/ 18 апреля 2010

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

В качестве альтернативы, я мог бы использовать перегрузку и сделать конструктор по умолчанию закрытым.В таком случае я также хотел бы сделать приватным конструктор фабрики по умолчанию в объекте-компаньоне, как бы я это сделал?

Большое спасибо.

Адам

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

Ответы [ 4 ]

23 голосов
/ 08 сентября 2010

У вас нет возможности изменить способ, которым конструктор по умолчанию хранит свои параметры (например, путем изменения параметров до того, как они будут сохранены как 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.

11 голосов
/ 03 сентября 2010

Наличие вторичных конструкторов класса case не заставляет компилятор создавать дополнительные методы фабрики в компаньоне класса, поэтому вы не получите удобство CaseClaseName(«secondary constructor parameter list»>) для их создания. Вам придется использовать ключевое слово new.

Лучше поместить тип логики, который вы описываете, в альтернативные фабричные методы в объекте-компаньоне и придерживаться использования основного конструктора.

3 голосов
/ 18 апреля 2010

Вы можете перегружать конструкторы. Это так же, как в C ++ или Java. Просто создайте другой конструктор.

class Foo( _input:Int ){
    def this() = this( 0 )
}

Или вы можете увидеть это ТАК сообщение.

1 голос
/ 05 сентября 2010

Вы можете превратить обычный класс в псевдо-case-класс, написав собственные методы apply (для фабрики) и unapply (для сопоставления с образцом) в объекте-компаньоне. Или вы можете просто написать именованный фабричный метод в сопутствующем объекте класса дела.

...