0

So I am doing a program that works by having inputing a price and then using that price along with set values to do a calculation across two child classes that inherit from a superclass where a class is called there which is where the price is kept the issue I have is that whenever I call upon the payment calculation method I get a NullPointerException

package Lab1;
import java.util.Scanner;

public class main{
    public static void main(String[] args){
        Car c = new Car("model",1998, 123);
        ThirdPartyPolicy tp = new ThirdPartyPolicy("hello");
        ComprehensivePolicy comp = new ComprehensivePolicy(2,31);
        
        Scanner scan = new Scanner(System.in);
        System.out.println("Input price of car");
        c.price= scan.nextDouble(); 
       
        tp.printtp();
        comp.printcp();
         comp.calcPayment();
    }
}

 class Car{
     String model;
     int ManufacturingYear;
     double price;

     //constructor
     public Car(String model, int ManufacturingYear, int price){
     this.model=model;
     this.ManufacturingYear=ManufacturingYear;
     this.price=0;
     
     }
     enum CarType {
         SUV,
         SED,
         LUX,
         HATCH,
         ETC,
     }
    public double getprice(){
        return price;
    }
}

abstract class InsurancePolicies{
    String policyHolderName;
    int id;
    Car car;
   
    int numberofclaims = 1;
    double premium;
    
    int flatRate = 150;

    
    double calcPayment(){
    this.premium = ((car.price/100)+(numberofclaims*200)+flatRate);
    return premium;
    }
 
    public void print(){
    System.out.println(premium);
    }
   
}




class ThirdPartyPolicy extends InsurancePolicies{
    String comments;
    public ThirdPartyPolicy(String comments){
     this.comments=comments;
     }
    @Override
    public double calcPayment(){
    this.premium = ((car.price/100)+(numberofclaims*200)+flatRate);
    System.out.println( premium);
    return premium;
    }
    
    public void printtp(){
        super.print();
    
   
    
    
}
}
class ComprehensivePolicy extends InsurancePolicies{
int driverage;
int level;
public ComprehensivePolicy(int level, int driverage){
       
     this.level=level;
     this.driverage=driverage;
     
     }


    public Car getCar() {
        return car;
    }
    @Override
    double calcPayment(){
    this.premium = ((car.price/100)+(numberofclaims*200)+flatRate);
    if (driverage<30){
        this.premium += ((30-driverage)*50);
        return premium;
    }
    return premium;
    }

    public void printcp(){
        super.print();

    }
}



If anyone can help me resolve this issue that would be appreciated

2 Answers2

1

InsurancePolicieshave a Car variable that is never initialized, so it's null by default. You should inform the car via polices' constructor or some kind of set method, before call de calculation.

S4NR-3000
  • 57
  • 5
0

I pasted your code and ran it locally. When prompted, I entered "100". Here's the entire output:

Input price of car
100
0.0
0.0
Exception in thread "main" java.lang.NullPointerException: Cannot read field "price" because "this.car" is null
    at ComprehensivePolicy.calcPayment(main.java:102)
    at main.main(main.java:17)

Why did that fail? Because Car car; is declared in the abstract class, and code tries to use it (car.price) without first assigning a value or creating a Car object. So, car is null, and calling anything on it (like "car.price") will throw NullPointerException.

Here's a very simple fix to get it working: right after creating a new "ThirdPartyPolicy", assign the car you created a few lines earlier:

Car c = new Car("model", 1998, 123);
...
ThirdPartyPolicy tp = new ThirdPartyPolicy("hello");
tp.car = c;

After doing that, you'll see another exception which looks identical to the first. It's due to the shared code in the abstract class, again with null "car". Here's a similar simple fix to get it working.

ComprehensivePolicy comp = new ComprehensivePolicy(2, 31);
comp.car = c;

After adding both of those lines, the program runs without error.

Here's a cleaner way of making things work.

  1. Modify the "ThirdPartyPolicy" constructor to require a Car parameter, and save the reference (this.car = car):
    public ThirdPartyPolicy(Car car, String comments) {
        this.comments = comments;
        this.car = car;
    }
    
  2. Similar change for "ComprehensivePolicy":
    public ComprehensivePolicy(Car car, int level, int driverage) {
        this.car = car;
        this.level = level;
        this.driverage = driverage;
    }
    
  3. Pass the "car" reference to each of the constructors:
    Car car = new Car("model", 1998, 123);
    ThirdPartyPolicy tp = new ThirdPartyPolicy(car, "hello");
    ComprehensivePolicy comp = new ComprehensivePolicy(car, 2, 31);
    
Kaan
  • 5,434
  • 3
  • 19
  • 41