3

给定两个类:

 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)”就好了。即使在这种情况下,事情也会变得模糊不清。

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

4

5 回答 5

2

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


通过@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)

几乎一样简洁并且不会产生匿名类,但缺点是不重用argAas 指定的默认值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
于 2012-10-29T09:16:06.367 回答
1

argA实例化时覆盖:

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

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

于 2012-10-29T08:06:49.507 回答
1

只需在类定义中传递它:

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

val cb = new ClassB( 3 )
于 2012-10-29T08:30:47.703 回答
0

只需将参数传递给 ClassA:

class ClassB extends ClassA(3) { ... }
于 2012-10-29T07:04:54.100 回答
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()
于 2012-10-29T08:26:48.323 回答