据我所知,自定义构造函数的语义通常是通过伴生对象添加到类中的。那么,有没有办法在继承类的同时继承一个自定义构造函数呢?
一方面,我发现伴随对象不是沿着case类综合继承的,另一方面,我不知道有一种方法可以在类本身内创建自定义构造函数,以便继承它们。然而,对我来说,继承自定义构造函数似乎是一个非常有效的用例。那么在Scala中是否以某种(简单的)方式支持它呢?
天真的意图演示:
class A {}
object A {
def apply(n: Int) = {
println(n)
new A
}
}
class B extends A {}
object Test {
val a1 = A
val a2 = A(3)
val b1 = B // compile error
val b2 = B(3) // compile error附注:我甚至发现the arcane/deviant technique of defining this custom constructors导致了一个自定义构造函数,实际上它不会被继承(它确实适用于创建自定义构造函数,但很奇怪,不幸的是,这些构造函数不会被继承)。演示代码:
class A {
def this(n: Int) = {
this
println(n)
}
}
class B extends A {}
object Test {
val a1: A = new A
val a2: A = new A(3)
val b1 = new B
val b2 = new B(3) // compile error
}Intent Edit的澄清:
考虑到这个问题,“构造函数”和“伴生工厂方法”是可以互换的。
发布于 2015-10-03 00:49:29
你不能直接继承构造函数,因为你不能,你也不能继承没有一点工作就使用它们的东西。但是您可以抽象出构造函数调用之外的任何东西。
让我们假设我们有
class Foo(text: String) {
override def toString = "Foo: " + text
}
object Foo {
def apply(text: String) = new Foo(text) // Auto-generated for case class
def apply(i: Int) = new Foo(
if (i > 0) i.toString
else if (i == 0) ""
else s"negative ${0L - i}"
)
}然后我们决定
class Bar(text: String) extends Foo(text) {
override def toString = "Bar: " + text
}现在,我们该如何处理object Bar呢?我们创建了一个特征,将对象创建与构造函数参数的计算分离和抽象,而不是重新编写所有的逻辑:
trait FooCompanionLike[A <: Foo] {
def apply(text: String): A // I am abstract!
def apply(i: Int): A = apply(
if (i > 0) i.toString
else if (i == 0) ""
else s"negative ${0L - i}"
)
}现在我们可以
object Foo extends FooCompanionLike[Foo] {
def apply(text: String) = new Foo(text)
}
object Bar extends FooCompanionLike[Bar] {
def apply(text: String) = new Bar(text)
}因此,您不能完全摆脱样板,但您可以将其简化为从一个特征和单个方法调用扩展。
如果您这样做(其中抽象apply与构造函数完全匹配),您甚至可以让case类工作,而无需在附带中手动定义抽象apply方法:
case class Baz(text: String) extends Foo(text) {
override def toString = "Baz: " + text
}
object Baz extends FooCompanionLike[Baz] {
// Nothing here! Auto-generated apply works!
}发布于 2015-10-03 01:30:46
简短的回答:没有直接的方法;试着变通并抵制这种渴望。
发布于 2015-10-03 00:15:24
Scala中的构造函数定义在类的主体中,并在类名之后接受参数。
class A(i: Int) {
println(i)
}本例中的println(i)是构造函数逻辑。如果现在扩展A,如下所示:
class B(i: Int) extends A(i)实例化B,val b1 = new B(2),你会看到构造函数确实是继承的。
正如您已经发现的,Scala允许您通过定义名为this的函数来定义替代构造函数。但是这些替代构造函数必须调用主构造函数。
我的理解是,任何Scala类实际上只有一个构造函数,可选的构造函数只是在其中进行过滤。例如:
class A(x: Int, y: Int) {
// do some constructing!
def this(x: Int) = {
this(x, 1) // provide a default value for y
}
}https://stackoverflow.com/questions/32910646
复制相似问题