3

与えられた 2 つのクラス:

 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)

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
于 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 に答える