Reputation: 4702
I am trying to pass an enum as a parameter to another class, so I can override its price Value. Here is my approach:
Base class Product:
open class Product(val productName: String, open val price: Double) {
val profit = price
}
Enum class:
enum class Discount(val factor: Int) {
BIGSALE(20),
LITTLESALE(10),
NOSALE(0)
}
Discount Product:
class DiscountProduct(
val discount: Discount,
productName_param: String, price_param: Double
) : Product(productName_param, price_param) {
// Nullpointer Exception
override val price: Double
get() = super.price - ((super.price / 100) * discount.factor)
}
App (main):
val newProduct = DiscountProduct(Discount.BIGSALE, "Prod1", 100)
I appreciate every help. Thank you!
ERROR:
Exception in thread "main" java.lang.NullPointerException
at DiscountProduct.getPrice(DiscountProduct.kt:6)
at Product.<init>(Product.kt:2)
at DiscountProduct.<init>(DiscountProduct.kt:3)
at AppKt.main(App.kt:2)
at AppKt.main(App.kt)
Upvotes: 0
Views: 461
Reputation: 58427
The actual constructor for DiscountProduct
, when viewed as Java code, will look something like this:
public DiscountProduct(@NotNull Discount discount, @NotNull String productName_param, double price_param) {
Intrinsics.checkParameterIsNotNull(discount, "discount");
Intrinsics.checkParameterIsNotNull(productName_param, "productName_param");
super(productName_param, price_param);
this.discount = discount;
}
So the super
constructor (i.e. Product
's constructor) is called first, and then the discount
member is initialized.
Product
's constructor looks something like this:
public Product(@NotNull String productName, double price) {
Intrinsics.checkParameterIsNotNull(productName, "productName");
super();
this.productName = productName;
this.price = price;
this.profit = this.getPrice();
}
When you get to this.profit = this.getPrice();
(which corresponds to the kotlin line val profit = price
) you're calling DiscountProduct
's getPrice
method, which tries to use the discount
member, which hasn't yet been initialized. And that's why you get a NullPointerException
.
There are probably a few different ways in which you could fix this. One possible solution would be to make profit
a lazy property, so that it doesn't get initialized until the first time you try to use it:
val profit: Double by lazy { price }
Another possible solution would be:
val profit: Double get() = price
The difference between this and a lazy property is that here the price gets calculated every time you use profit
, not just the first time.
Upvotes: 2