2017-09-09 5 views
2

は、我々は次のように設定していると言うNPE作成:初期化時にオーバーライド変数が変数は、スーパークラスで初期化に使用される場合に

open class Foo(open val img: Image) { 
    val use = img.graphics 
} 
class Bar(override val img: BufferedImage) : Foo(img) 

を、img.widthの使用は、NPEを作成します。私が問題と思うのは、明らかにimgがFooのコンストラクタでBarに直接渡されても、Fooで使用されているときに、Barクラスのオーバーライドされた変数を指しています。どうすればこれを避けることができますか?

答えて

1

この動作はimgのゲッターが上書きされるという事実に起因すると(異なるタイプBarオーバーライドimgので、それはタイプBufferedImageの追加フィールドを作成する必要が)別のフィールドの値を返しています。 Fooコンストラクタは、そのフィールドがBarに割り当てられる前に実行されます。一般的に

、彼らはサブクラスでオーバーライドすることができると、スーパークラスの初期化時間に、適切にまだ初期化されていないいくつかの状態に依存している可能性があるため、あなたが、あなたのクラスの初期化ロジックで開いたメンバーを使用しないでください。あなたの特定のケースについては

、簡単なパラメータ Fooコンストラクタで imgを作成し、明示的パラメータを使用します。

open class Foo(img: Image) { 
    open val img = img 
    val use = img.graphics 
} 
関連する問題