Scala:如何设置抽象超类构造函数中定义的实例字段?

时间:2012-10-29 06:57:40

标签: scala inheritance parameters constructor arguments

给出两个类:

 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这样的几十个子类,所以如果不需要重写那就好了 “(val argA:Int = 1)”在每个类定义中。即使在这种情况下,事情也会模糊不清。

我发现的最相似的问题是获取,而不是设置值: question

5 个答案:

答案 0 :(得分:2)

正如您所看到的,有几种可能的方法可以实现您的要求。但是,哪一个是最佳方式并不明显,因为这取决于您希望强调的内容(简洁性,重用性,性能)以及实际代码的外观。值得记住的一些事情是:


使用@ maackle's的解决方案,每个表单的实例化

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)

几乎是简洁的,不会导致匿名类,但缺点是argA指定的默认值ClassA不会被重用(它在@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

答案 1 :(得分:1)

在实例化时覆盖argA

val b = new ClassB {
    override val argA = 3
}

根据你所写的内容,这似乎是做你想要的最简洁的方式。根据您的实际使用情况,您可能会发现通过在随播对象上定义某些方法来实例化对象的一些不那么笨重的方法。

答案 2 :(得分:1)

在类定义中传递它:

class ClassB( i: Int ) extends ClassA(i) { ... }

val cb = new ClassB( 3 )

答案 3 :(得分:0)

只需将参数传递给ClassA:

class ClassB extends ClassA(3) { ... }

答案 4 :(得分:0)

abstract class ClassA {
    val argA: Int = 1
    def func1() {
        println(argA)
    }
}

class ClassB extends ClassA {
    def func2() {
        println("B: %d" format argA)
    }
}

val b = new ClassB { override val argA = 3 }
b.func1()