给定两个类:
abstract class ClassA(val argA:Int = 1) {
def func1 {
... argA ... //some operations
func2
}
def func2
}
class ClassB extends ClassA {
def func2 {
... argA ... //some operations
}
}
val b = new ClassB
b.func1
如何在实例化 b 时传递 argA=3? 像B这样的child-class会有几十个,不用重写就好了 每个类定义中的“(val argA:Int = 1)”。即使在这种情况下,事情也会变得晦涩难懂。
我发现的最相似的问题是关于获取而不是设置值: question
最佳答案
如您所见,有几种可能的方法可以实现您的要求。但是,哪一个是最好的方法并不明显,因为这取决于您希望强调什么(简洁、重用、性能)以及您的实际代码的外观。一些值得记住的事情是:
使用@maackle 的解决方案,表单的每个实例化
val b = new ClassB { override val argA = 3 }
将导致在幕后创建的匿名类 class AnonSubB extends ClassB
。如果你想专注于简洁,那么这可能是要走的路,但如果匿名类的数量增加,它们可能会减慢编译速度。
@paradigmatic 的解决方案
class ClassB(i: Int) extends ClassA(i) { ... }
val cb = new ClassB(3)
几乎一样简洁并且不会产生匿名类,但缺点是 ClassA
指定的 argA
的默认值不会被重用(它是在@maackle 的解决方案中)。您可以重复该值,即将 ClassB
声明为
class ClassB(i: Int = 1) extends ClassA(i) { ... }
但这很容易出错,因为如果需要更改,您必须在各个地方更改默认值。
我还想提供一个我自己的解决方案,重点在于重用默认值而不创建匿名类,但不够简洁:
/* ClassA has a reusable (referenceable) default value */
abstract class ClassA(val argA: Int) {
def this() = this(ClassA.defaultArgA)
}
object ClassA {
val defaultArgA = 1
}
/* ClassB reuses ClassA's default value */
class ClassB(x: Int = ClassA.defaultArgA) extends ClassA(x)
/* ClassC has a local (non-referenceable) default value */
class ClassC(x: Int = 10) extends ClassA(x)
println(new ClassB(2).argA) // 2
println(new ClassB().argA) // 1
println(new ClassC().argA) // 10
关于Scala:如何设置在抽象父类(super class)构造函数中定义的实例字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13117149/