Scalaをよりよく理解しようとしていますが、次のようなコードの有効なユースケースが見つからないようです。
class C extends { def m() { /* ... */ } }
そのような構成を許可する理由は何ですか?
ありがとう!
Scalaをよりよく理解しようとしていますが、次のようなコードの有効なユースケースが見つからないようです。
class C extends { def m() { /* ... */ } }
そのような構成を許可する理由は何ですか?
ありがとう!
ここでの唯一の論理的根拠は、「可能であれば特別な場合を避ける」ことだと思います。任意のクラスを拡張できます。匿名クラスはクラスであるため、匿名クラスを拡張できます。
実際、それは匿名のクラスではありません!これは初期の初期化子であり、スーパークラスの前にあるコンストラクターの一部として実行されます。別のstackoverflowの質問から優れた答えを引用する:
abstract class X {
val name: String
val size = name.size
}
class Y extends {
val name = "class Y"
} with X
コードが代わりに次のように記述されている場合
class Z extends X {
val name = "class Z"
}
次に、Zが初期化されると、nullポインター例外が発生します。これは、サイズが初期化の通常の順序(クラスの前のスーパークラス)で名前の前に初期化されるためです。
これは初期定義と呼ばれ、スーパークラスの初期化順序の問題を扱います。