OOP门票价格计划

时间:2017-05-05 18:07:33

标签: java oop if-statement while-loop

所以这个有点冗长。我正在尝试完成一个程序,其中票价根据​​购买日期而有所不同。我需要Tester.Java从对象中获取信息,并根据票证类型输出适当的价格。我已经在测试程序中设置了一组if语句,但我现在对如何完成此程序有所了解。我将在下面粘贴我的代码。

Tester(包含主要方法):

package tester;
import java.util.Scanner;

public class Tester extends Ticket{
/**
 * @param args the command line arguments
 */
public static void main(String[] args){
    Scanner db = new Scanner(System.in);
    Ticket firstTicket = new Ticket();
    System.out.println("The first ticket: "+firstTicket.toString());
    int x = 0;
    while(x!=2){
        if(x==2){
            System.out.println("Goodbye.");
        }
        else{
           System.out.println("What type of ticket are you purchasing?");
           System.out.println("1.Walk Up");
           System.out.println("2.Advance");
           System.out.println("3.Student Advance");
           int t = db.nextInt();
           if(t==1){

           }
           if(t==2){

           }
           if(t==3){

           }

        }
     System.out.println("Do you need another ticket?");
     x= db.nextInt();            
    }        
  }   
}

门票(超级班):

package tester;

import java.util.Scanner;

public class Ticket {
    public int ticket;
    public double price;
  /**
   * holds default values for ticket number and price
   */
  public Ticket(){
    super();
    this.ticket=1;
    this.price=15.0;        
  }

  /**
   * Stores the values for ticket number and the price, based upon ticket type
   * @param ticket
   * @param price 
   */
  public Ticket(int ticket, double price){
    this.ticket=ticket;
    this.price=price;   
  }

  /**
   * returns the value of price
   * @return price
   */
  public double getPrice(){
    return price;
  }

  @Override
  public String toString(){
    return "Ticket #" + ticket + " Ticket price: $"+ price; 
  }
}

Walkup Ticket:

package tester;

/**
 *
 * @author dylan
 */
public class WalkupTicket extends Ticket{

/**
 * holds the price of a walkup ticket 50$
 */
public WalkupTicket(){
    this.price=50;
    ticket++;
  }
}

预售票:

package tester;

import java.util.Scanner;

public class AdvanceTicket extends Ticket {    
  /**
   * stores the values of an advance ticket, depending on how many days before
   * the event it is purchased
   */
  public AdvanceTicket(){
    Scanner db = new Scanner(System.in);
    System.out.println("How many days before the event are you purchasing your ticket?");
    int days = db.nextInt();
    // days before is 10 or less days
    if(days >= 10){
      price=30;
      ticket++;
    }
    // days before is more than 10
    else{
        this.price=40;
        ticket++;
    }
  }
}

学生预售票:

package tester;

import java.util.Scanner;

public class StudentAdvanceTicket extends AdvanceTicket{
  /**
   * stores the values of an advance ticket, depending on how many days before
   * the event it is purchased, with student discount.
   */
  public StudentAdvanceTicket(){
   Scanner db = new Scanner(System.in);
    System.out.println("How many days before the event are you purchasing your ticket?");
    int days = db.nextInt();
    System.out.println("Are you a student?");
    System.out.println("1. Yes");
    System.out.println("2. No");
    int stud = db.nextInt();
    // days before is 10 or less days
    if(days >= 10 && stud == 1){
      price=15;
      ticket++;
    }
    // days before is more than 10
    if(days <= 10 && stud == 1){
        this.price=20;
        ticket++;
    } 
  }
}

我觉得我犯的是一个简单的错误,但我是OOP的新手,所以我对此有点麻烦。

2 个答案:

答案 0 :(得分:1)

您是否应该为所有购买的门票保存总额,或者一次只保存一张门票?

对于步行门票,您不必做任何事情。它总共50美元。

对于Advance和StudentAdvance,您将创建一个该类型的新对象,并且您拥有它的方式构造函数将显示提前多少天的菜单。然后,您可以从中获得总数。

至于你的代码结构,它并不理想。对象的构造函数不应该包含所有代码。他们应该有一个ShowMenu函数,它将向用户显示菜单并读取他们的输入。构造函数在大多数情况下应该是空白的。

您也不需要三个不同的票证对象。一个票证对象应该能够自己处理所有这些。故障单对象可以显示菜单并根据用户输入处理不同的价格。如果需要保存总票数或不同票证,则可以在main方法上拥有一组票证对象。然后,您可以遍历该数组以显示或汇总票证。

希望这有帮助。

答案 1 :(得分:0)

你的问题非常广泛,但是对你的意见有些想法:

  • 名称很重要。你做了第一步并且使用特定的包(而不是默认包)是很好的;但是tester没有。你可以称它为dylan.tickets例如:明确A)你的东西和B)它是关于那个票系统
  • 您似乎认真对待自己的工作,因此:不要使用 static main 来驱动测试用例。使用JUnit和简单的测试用例非常简单。除此之外:使用主机“手动”驾驶测试是麻烦且容易出错的。单元测试几乎自动自动化。
  • 更重要的是:只是打印的测试几乎没用。如果您的代码出现意外行为,您可能只会在仔细检查打印输出时注意到。如上所述:使用单元测试,Junit断言调用以检查方法调用的预期结果与实际结果。因为那时你会被告知当你做出改变以破坏以前工作的功能时。
  • 绝对避免在很多不同的地方要求用户输入。含义:合理的是一个类有一个构造函数或setter方法;并且实例化新对象所需的所有参数都是赋予到该对象。如果有的话,您的会使用扫描仪并要求用户输入。但是所有“业务逻辑”对象根本不需要任何“用户交互”。你知道,你实际上想要开始整个项目而不用使用扫描仪。您希望硬编码类似AdvancedTicket at = new AdvancedTicket(100);之类的内容 - 因为现在您可以轻松编码各种不同的对象;并一次又一次地启动你的程序。您当前的解决方案要求您手动输入所有此类数据...每次重新启动程序时!所以:构造函数中没有扫描仪使用。决不!
  • 然后:好的OO是关于行为,而不是关于状态。含义:您不使用公共字段来传播信息。如果有的话,您的字段应受保护;但即使这通常也不是一个好主意。你想把你的班级彼此隔离......
  • 核心问题:似乎没人告诉你FCoI。你应该支持组合而不是继承。含义:你不要只把A extends B放在任何地方。绝对没有理由让您的Tester类扩展 Ticket。测试人员是测试人员,而不是门票!

如上所述:最后一点是最重要的一点。你是小心关于使A成为B的子类;通常情况下,让A 拥有 B对象更合适,但不能使A成为B!