Reputation: 1376
Say we have the following set up:
open class Foo(open val img: Image) {
val use = img.graphics
}
class Bar(override val img: BufferedImage) : Foo(img)
On initialization, the use of img.width
creates a NPE. What I think the issue is, is that apparently even though img
is passed in the constructor of Foo directly in Bar, when it is used in Foo it doesn't point to it, instead it points to the overridden variable in the Bar class. How can I avoid this?
Upvotes: 2
Views: 77
Reputation: 147901
This behavior is caused by the fact that the getter of img
is overridden and returns the value of a different field (since Bar
overrides img
with a different type, it requires creating an additional field of type BufferedImage
). The Foo
constructor is executed before that field is assigned in Bar
.
In general, you should avoid using open members in the initialization logic of your classes, because they may be overridden in the subclasses and may rely on some state that, upon the superclass initialization time, is not properly initialized yet.
For your particular case, make img
in the Foo
constructor a simple parameter and use the parameter explicitly:
open class Foo(img: Image) {
open val img = img
val use = img.graphics
}
Upvotes: 2