mynameisJEFF
mynameisJEFF

Reputation: 4239

Java Object Oriented Programming: failed to update instance variable

Basically, I created an abstract class Ticket to prevent instantiation of the Ticket class. This Ticket class is a superclass of the WalkupTicket. I am supposed to implement TicketMain class to print out the price and ticket number of WalkupTicket. And I am not allowed to pass price as parameter into the constructor. Below is the code that I wrote. However, the instance variable price never get updated. I do not know what went wrong.

I am sure I must have some misunderstanding in inheritance / polymorphism. Please point out my mistakes. Thanks.

public abstract class Ticket{
       // Fields
       private int tixNumber;
       private double price;

      // Constructor
      public Ticket(int tixNumber){
          this.tixNumber = tixNumber;
      }

     // Instance method
     public double getPrice(){
            return price;
     }

     public int getTixNumber(){
           return tixNumber;
     }

      public String toString(){
           return "Number: " + getTixNumber() + ", Price: " + getPrice();
     }        
}

public class WalkupTicket extends Ticket{
     // Fields
     private double price;

     // Constructor
     public WalkupTicket(int tixNumber){
         super(tixNumber);
         this.price = 50.0;
     }
}

public class TicketMain{
      public static void main(String[] args){
            WalkupTicket ticket1 = new WalkupTicket(2);
            System.out.println( ticket1.toString() );
      }
}

The output is:

Number: 2, Price: 0.0

which is not what I want. I want the output to be:

Number: 2, Price: 50.0

Upvotes: 0

Views: 156

Answers (2)

Simone Gianni
Simone Gianni

Reputation: 11672

Your price field is private, and the one in the WalkupTicket is also private, they are two distinct fields.

"private" means it's not accessible to anyone, not even subclasses, so you have two distinct "price" fields, and are assigning to one and reading another.

There are many ways to do what you want.

If the field needs to be accessible to subclasses, declare it protected double price; and declare it only on the Ticket class.

If you want to make the price changeable, but not let subclasses freely access to it, then add a setter in Ticket :

public void setPrice(double price) {
  this.price = price;
}

Eventually, as before, if you want the setter to be callable only by subclasses, use protected instead of public.

If you want a slightly different and not common approach, override the getter, since is the getter you are using to access the field. So in class WalkupTicket :

public double getPrice() {
  return this.price;
}

The code is the same as the getter in the Ticket class, but this getter will override the previous and return the price field of WalkupTicket. But well .. it works, use it to understand how things works, but don't do it in practice cause it only makes the code harder to read in this case.

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347294

The value of the field price in WalkupTicket is not accessible from Ticket, you need to override the getPrice method...for example...

public class WalkupTicket extends Ticket{
    // Fields
    private double price;

    // Constructor
    public WalkupTicket(int tixNumber){
        super(tixNumber);
        this.price = 50.0;
    }

    public double getPrice() {
        return price;
    }
}

A better solution would be to provide a protected method in the Ticket class that allows you to set the price value...

public abstract class Ticket{
    //...
    protected void setPrice(double price) {
        this.price = price;
    }
    //...
}

Then you won't need the price variable in WalkupTicket at all and can simply set the price value via the setter...

public class WalkupTicket extends Ticket{

    // Constructor
    public WalkupTicket(int tixNumber){
        super(tixNumber);
        setPrice(50.0);
    }
}

Upvotes: 3

Related Questions