0

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)
1
  • 1
    You should post the exception stacktrace. Commented Apr 26, 2020 at 14:45

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.