W Scali, Jak mogę podklasować klasę Java z wieloma konstruktorami?
Załóżmy, że mam klasę Javy z wieloma konstruktorami:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
Jak mogę rozszerzyć go w Scali i nadal zapewnić dostęp do wszystkich trzech konstruktorów bazy? W Scali podklasa może wywoływać tylko jeden z konstruktorów klasy superklasy. Jak mogę obejść tę zasadę?
Załóżmy, że Klasa Java jest kodem dziedziczonym, którego nie mogę zmienić.
4 answers
Łatwo zapomnieć, że cecha może rozszerzyć klasę. Jeśli użyjesz cechy, możesz odłożyć decyzję o wywołaniu konstruktora, w następujący sposób:
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
}
Cechy mogą same w sobie nie mieć parametrów konstruktora, ale można to obejść, używając zamiast tego elementów abstrakcyjnych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-21 13:57:15
Edytuj - to jest z pytania na liście mailingowej scala, które myślałem, że został powielony tutaj. Moja odpowiedź dotyczy dostarczenia trzech różnych konstruktorów (tj. replikacji projektu Java), a nie rozszerzenia klasy
Zakładając, że każdy z konstruktorów ostatecznie tworzy Stan S
aby utworzyć obiekt towarzyszący za pomocą metod "statycznych", należy utworzyć ten stan
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")
}
Następnie utwórz prywatny konstruktor biorąc stan i (public) overloaded constructors that defer to the primary constructor
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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-21 14:16:05
Jest to głupia odpowiedź, która prawdopodobnie zadziałałaby nieco, ale może być zbyt dużym wysiłkiem, jeśli Klasa Java ma zbyt wiele konstruktorów, ale:
Napisz podklasę w Javie, która implementuje konstruktor, który pobiera wszystkie dane wejściowe, które Inne konstruktory wykonałyby i wywołuje odpowiedni konstruktor swojej superklasy w oparciu o obecność lub brak danych wejściowych (poprzez użycie "null" lub jakiegoś rodzaju wartości sentinel), a następnie podklasę tę klasę Javy w Scali i przypisać wartości sentinel jako domyślne parametry.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-21 13:59:15
Wybrałbym najbardziej ogólny (w tym przypadku String) i sam dokonałbym wewnętrznej konwersji, jeśli spełnia inne kryteria.
Choć przyznaję, że nie jest to najlepsze rozwiązanie i coś wydaje mi się w tym złe. :-(
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-21 13:36:34