2

値を定義するときにこのコードを Scala に持っていaます。また、オブジェクト内のいくつかのメソッドを呼び出しますsetStr。これは非常に便利で驚くべきものです。しかし、私AClassが最終として定義すると、コンパイラは最終クラスからの不正な継承として例外をスローします。場合によっては、最終クラスを使用する必要があり、クラス開始後のこのタイプのメソッド呼び出しは非常に便利です。私の質問は、この問題を解決する方法です

test("Test function call") {
    val a: AClass = new AClass {
        setStr("Pooya")
        func1(this)
    }
}

class AClass { // when I declare the class final, the compiler will raise an error
    private var str:String=""
    def setStr(str:String)={
        this.str=str
    }
    def aMethod() = print(str)
}

def func1(a: AClass) {
    a.aMethod()
}
4

2 に答える 2

3

これを行うと、このクラスを拡張する匿名クラスnew AClass { ... }が作成されます。クラスがである場合、それを拡張することはできません。final

あなたが望むことをする1つの方法はそのようなものです:

val a: AClass = new AClass 
import a._
setStr("Pooya")
func1(this)

@Vladimirの提案に従って、少しきれいな方法:

val a: AClass = { val a = new AClass 
  import a._
  setStr("Pooya")
  func1(this) 
  a 
}

setStrこれで、あいまいにすることなく、何度でも繰り返すことができます。の場合、func1現在の定義では、{}ブロック内にあるかどうかは問題になりません。

于 2013-07-21T14:30:41.947 に答える
1

finalセマンティクスを取得するには、初期状態をコンストラクターに渡します。

もう 1 つのモードは、初期定義を使用することです。BClass#strs が final であることに注意してください。

Final は、イニシャライザが完了したら、値を変更してはならないことを意味します。

そして可変状態を失います。

しかし、可変性が好きな場合や可変性が必要な場合は、コンパニオン オブジェクトのファクトリは、オブジェクトを構築するときに必要な正気度を問わず機能します。

package inheritthewind

object Test extends App {
  val a = new AClass(new AInit { val str = "Pooya" })
  a.aMethod()
  val b = new {
    val str: String = "Pooya"
  } with BClass
  b.aMethod()
  val b2 = new BClass {
    val str: String = "Pooya"
  }
  b2.aMethod()  // uh no, result is "nulls"
  val c = CClass(new CPrototype { val str = "Pooya" })
  c.aMethod()
  // not allowed
  //val nope = new CClass
}

trait AInit {
  def str: String
}

final class AClass(init: AInit) {
  private final val str: String = init.str
  def aMethod() = Console println str
}

abstract class BClass {
  val str: String
  final val strs = str + "s"
  def aMethod() = Console println strs
}

trait CPrototype extends AInit

final class CClass private() {
  private var str: String = _
  def aMethod() = Console println str
}
object CClass {
  def apply(p: CPrototype): CClass = {
    val res = new CClass
    res.str = p.str
    res
  }
}

scala> :javap -pv inheritthewind.BClass
[snip]
  private final java.lang.String strs;
    flags: ACC_PRIVATE, ACC_FINAL

  public abstract java.lang.String str();
    flags: ACC_PUBLIC, ACC_ABSTRACT

  public final java.lang.String strs();
    flags: ACC_PUBLIC, ACC_FINAL
于 2013-07-22T07:14:47.680 に答える