Java面向对象编程:无法更新实例变量



基本上,我创建了一个抽象类Ticket来防止Ticket类的实例化。这个Ticket类是WalkupTicket的一个超类。我应该实现TicketMain类来打印WalkupTicket的价格和票号。并且不允许我将price作为参数传递到构造函数。下面是我写的代码。但是,实例变量price永远不会更新。我不知道出了什么问题。

我确信我在遗传/多态性方面一定有一些误解。请指出我的错误。谢谢

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() );
      }
}

输出为:

Number: 2, Price: 0.0

这不是我想要的。我希望输出为:

Number: 2, Price: 50.0

WalkupTicket中字段price的值无法从Ticket访问,您需要重写getPrice方法。。。例如

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;
    }
}

更好的解决方案是在Ticket类中提供一个protected方法,允许您设置price值。。。

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

那么您根本不需要WalkupTicket中的price变量,只需通过setter设置price值即可。。。

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

您的价格字段是私有的,WalkupTicket中的价格字段也是私有的,它们是两个不同的字段。

"private"意味着任何人都无法访问它,甚至子类也无法访问,因此您有两个不同的"price"字段,它们分别分配给一个字段和读取另一个字段。

有很多方法可以做你想做的事。

如果子类需要访问该字段,请将其声明为protected double price;,并仅在Ticket类上声明。

如果你想让价格可变,但不让子类自由访问它,那么在Ticket:中添加一个setter

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

最后,和以前一样,如果您希望setter只能由子类调用,请使用protected而不是public。

如果您想要一种稍微不同且不常见的方法,请重写getter,因为它是用于访问字段的getter。所以在课堂上步行票:

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

代码与Ticket类中的getter相同,但此getter将覆盖前面的getter并返回WalkupTicket的价格字段。但是。。它是有效的,使用它来理解事情是如何工作的,但不要在实践中这样做,因为在这种情况下,它只会使代码更难阅读。

最新更新