В Scala, как я могу подкласс класса Java с несколькими конструкторами?
Предположим, у меня есть класс Java с несколькими конструкторами:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
Как я могу расширить его в Scala и по-прежнему предоставлять доступ ко всем трем конструкторам базы? В Scala подкласс может вызывать только один из его конструкторов суперкласса. Как я могу обойти это правило?
предположим, что класс Java является устаревшим кодом, который я не могу изменить.
4 ответа:
легко забыть, что признак может расширить класс. Если вы используете признак, вы можете отложить решение о том, какой конструктор вызывать, например:
trait Extended extends Base { ... } object Extended { def apply(arg1: Int) = new Base(arg1) with Extended def apply(arg2: String) = new Base(arg2) with Extended def apply(arg3: Double) = new Base(arg3) with Extended }
сами признаки могут не иметь параметров конструктора, но вы можете обойти это, используя вместо этого абстрактные члены.
EDIT -это из вопроса в списке рассылки scala, который, как я думал, был продублирован здесь. Мой ответ касается предоставления трех разных конструкторов (т. е. репликации дизайна Java), а не расширения класса
предполагая, что каждый из ваших конструкторов в конечном счете создать state
S
объекта, создать сопутствующий объект с "статическими" методами для создания этого состоянияobject Base { private def stateFrom(d : Double) : S = error("TODO") private def stateFrom(s : Str) : S = error("TODO") private def stateFrom(i : Int) : S = error("TODO") }
затем создайте частный конструктор, принимающий состояние и (публичные) перегруженные конструкторы, которые относятся к основному конструктору
import Base._ class Base private(s : S) { //private constructor takes the state def this(d : Double) = this(stateFrom(d)) def this(str : String) = this(stateFrom(str)) def this(i : Int) = this(stateFrom(i)) //etc }
Это глупый ответ, который, вероятно, будет работать несколько, но может быть слишком много усилий, если класс Java имеет слишком много конструкторов, но:
напишите подкласс в Java, который реализует конструктор, который принимает все входы, которые будут принимать различные другие конструкторы, и вызывает правильный конструктор своего суперкласса на основе наличия или отсутствия входов (с помощью использования "null" или каких-то значений sentinel), затем подкласс, который Java-класс в Scala и назначает sentinel значения параметров по умолчанию.