考虑以下设计的Java示例:
public class Example {
private final Object value;
private final List<?> aListOfTheseThings;
public <T> Example(final T t, final List<T> aListOfTheseThings) {
this.value = t;
this.aListOfTheseThings = aListOfTheseThings;
}
}
本例中我关心的是:
Example
未参数化t
(这是一个人为的例子,我并不真正关心(2)
,但我真的关心那里有一个类型参数,这在类的定义中没有提到。)
现在在Scala中我尝试了以下内容:
class Example private[this](
private val value: AnyRef,
private val aListOfTheseThings: List[_]) {
def this[T](t: T, aListOfTheseThings: List[T]) {
this(t, aListOfTheseThings)
}
}
......但这是不可能的。显然,类型参数在构造函数中无效(在this
中)。
是否有机会将上述Java代码翻译成Scala?
答案 0 :(得分:7)
也许这有帮助:
sealed trait Example
object Example {
def apply[T <: AnyRef](t:T, aListOfTheseThings: List[T]): Example =
new ExampleImpl(t, aListOfTheseThings)
private class ExampleImpl(
val value: AnyRef,
val aListOfTheseThings: List[_]) extends Example
}
这使得类Example
的私有构造函数成为可能。价值和aListOfTheseThings
不会通过Example
特征访问(除非您可以访问)
答案 1 :(得分:6)
Nyavro建议使用帮助apply
方法是一个很好的方法。在某些情况下可能适用的另一种选择是子类化:
trait Example {
val value: Any
val things: List[_]
}
class SameTypeExample[T](val value: T, val things: List[T]) extends Example
子类化的优点是value
和things
存储相同类型的约束不会丢失,并且可以通过模式匹配重新发现:
def handle(example: Example) = example match {
case st: SameTypeExample[t] =>
st.value :: st.things
}
子类化是Scala中用于暂时隐藏构造时存在的信息的一种通用技术。