Подтвердить что ты не робот

В Scala, как я могу подклассифицировать класс Java с несколькими конструкторами?

Предположим, что у меня есть класс Java с несколькими конструкторами:

class Base {
    Base(int arg1) {...};
    Base(String arg2) {...};
    Base(double arg3) {...};
}

Как я могу расширить его в Scala и предоставить доступ ко всем трем базовым конструкторам? В Scala подкласс может вызывать только один из его конструкторов суперкласса. Как я могу обойти это правило?

Предположим, что класс Java - это устаревший код, который я не могу изменить.

4b9b3361

Ответ 1

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

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
}

Черты не могут иметь параметры конструктора, но вы можете обойти это, используя вместо этого абстрактные элементы.

Ответ 2

EDIT - это вопрос из списка рассылки scala, который, как я думал, дублируется здесь. Мой ответ связан с предоставлением трех разных конструкторов (т.е. Для репликации дизайна Java) и не расширения класса

Предполагая, что каждый из ваших конструкторов в конечном итоге создает состояние 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
}

Ответ 3

Это глупый ответ, который, вероятно, будет работать несколько, но может быть слишком большим, если класс Java имеет слишком много конструкторов, но:

Напишите подкласс в Java, который реализует конструктор, который принимает все входы, которые могут использовать другие другие конструкторы, и называет соответствующий конструктор своего суперкласса на основе наличия или отсутствия входных данных (посредством использования "нулевого" или какого-то дозорного значения), затем подкласс, который Java-класс в Scala, и назначить значения дозорности в качестве параметров по умолчанию.

Ответ 4

Я бы выбрал наиболее общий (в данном случае String) и сам сделаю внутреннее преобразование, если оно соответствует другим критериям.

Хотя я признаю, что это не лучшее решение, и что-то кажется мне неправильным.: - (