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

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

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

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

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

57
задан Seth Tisue 21 July 2010 в 02:42
поделиться

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
}

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

89
ответ дан 7 November 2019 в 06:05
поделиться

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

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

2
ответ дан 7 November 2019 в 06:05
поделиться

РЕДАКТИРОВАТЬ - это из вопроса в списке рассылки 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
}
5
ответ дан 7 November 2019 в 06:05
поделиться

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

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

2
ответ дан 7 November 2019 в 06:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: