В Scala, как я могу создать подкласс Java-класса с несколькими конструкторами? - PullRequest
56 голосов
/ 21 июля 2010

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

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

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

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

Ответы [ 4 ]

89 голосов
/ 21 июля 2010

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

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
}

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

5 голосов
/ 21 июля 2010

РЕДАКТИРОВАТЬ - это вопрос из списка рассылки 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
}
2 голосов
/ 21 июля 2010

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

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

2 голосов
/ 21 июля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...