CS 151 Fall 2007 Lab 5:

Conditional Logic and flow control (if ... else, switch)

The goal for this lab is

 

  1. Open BlueJ either by selecting it from the Dock or navigating to it in the Applications folder and double clicking it.

  2. Mount your network directory/folder so that you can access the lab after you leave Olin 323.  Go to the Finder and from the Go menu select Connect to Server....  Type afp://fileserver1 or choose it from the list of selections and select the Personal volume when prompted.

  3. From the Project menu select New Project.  Select your computer from the drop down menu.  Then scroll down and open the Volumes folder and then the Personal folder inside it.  Scroll down the long list of folders until your find yours.  Create a project called "Lab5" in your personal network folder.

  4. Import your Automobile class from Lab 3 into your Lab5.  From the Edit menu select the "Add Class from File ..." option.  Navigate to the project/folder that contains your Automobile class.  Select the Automobile.java file or whatever you called yours, make sure the File Format in the bottom of the window is set to "Java Source", and click the "Add" button.  This will make a copy of the class in your current project.  If your previous lab's Automobile.java file isn't available or you prefer to use one of my Lab 3 solutions, download it from the course home page.  Then, use the above procedure for "Add Class from File" substituting the name of the file you downloaded and its location (the Desktop by default). 

 

  1. Modify the drive() method as we discussed in class to use and if {} else {} statement.  If the car has enough fuel, it drives the distance specified by drive() method's parameter.  Otherwise, it travels as far as it can on the fuel it has. 
    You may find it helpful to define two variables to store how far the car can go with the fuel it has, e.g. range, and how much fuel it will take to travel the distance specified in the drive method's parameter, e.g. fuelNeeded.  Add the
    if (   ) condition before the fuelLevel and fuelEfficiency assignments already in the method since you want those commands to execute if the condition you write in the parentheses is true.  Add the else clause after that and assign fuelLevel and fuelEfficiency the appropriate values.  Don't put a semi-colon at the end of the if (   ) line, and remember to use {  } to enclose multiple lines that should be executed together.  Test your method interactively to make sure that the car doesn't drive past its fuel limit and that the mileage updates correctly.

 

  1. Now modify the drive method again to see a different way of implementing the same check.  If you didn't do so in the previous step, define two variables to store how far the car can go with the fuel it has, e.g. range, and how much fuel it will take to travel the distance specified in the drive method's parameter, e.g. fuelNeeded.  Comment out the if ... else logic from the previous step by surrounding it with /* before and */ after.  Instead, use Math.max() and Math.min() so that there is a single assignment for the mileage and fuel level as before, i.e.
    fuelLevel = Math.   ( , );
    mileage = mileage + Math.   ( , );

    Decide in each case whether to use min or max and what should go it the parentheses.  Try to work through an example on paper first.  Do we also need a check to make sure that the fuelEfficiency is non-zero?  Why or why not?

 

  1. Add a private instance variable of the String type to the class.  Call it model or something like that (feel free to add a variable for the vehicle's make/manufacturer too if you like).  Then add constants (static final) to your class for at least 3 different models, e.g. PRIUS = "Prius", CIVIC = "Civic", TAURUS = "Taurus".   Also add another constant for each model's default fuel efficiency, e.g. CIVIC_EFFICIENCY = 39.0, etc.  It's good style to keep all instance variables together, usually all the public ones followed by the private ones.

 

  1. If your class doesn't already have one add a public setFuelEfficiency() method that takes a single double parameter and returns void.  It should set the fuelEfficiency variable/field to the specified parameter.  Next, add a second method public setFuelEfficiency() method that takes a single String parameter specifying the model of the car. e.g. Civic, Taurus, Prius, etc.  Be sure to use a different name for the method parameter than your used for the fuel level instance variable.  This String parameter version should determine the correct fuelEfficiency setting based on the object's model variable.  Use a sequence of nested "if () ... else if () ... else" tests to decide the correct setting and store it in a variable declared earlier in the method.  Test the String parameter against the constants for each model and assign a default value if the given parameter doesn't match any defined model.  Don't forget to use the .equals() method to compare strings.  The last line of the method should call the version that takes a double with the value you determined as an argument.
    setFuelEfficiency(String theModel)
    {
         double efficiency = 0;
         if (theModel.equals(Automobile.CIVIC))
              efficiency = Automobile.CIVIC_EFFICIENCY;
         else if (theModel.equals(     ))
              efficiency =      ;



         //call the other method to actually assign the value
         setFuelEfficiency(efficiency);
    }

 

  1. Add a constructor that allows the auto's model to be specified, but not the efficiency, e.g.
    Automobile(String modelName, double amount). 
    Use setFuelEfficiency(modelName) in the constructor to set the fuel efficiency based on the vehicle model.  When you have multiple constructors it can be tedious to modify them all.  There is a special use of the keyword this in constructors (see Advanced topic 3.1 online for syntax) that can lessen this problem.  Typically, your most generic constructor, the one that takes the most parameters, is where you write all your code and you have all the other constructors call that very general one using this(param1,param2, etc.).  However, the call to the other constructor must be the first line.  In our case this is minor inconvenience, since in the above constructor we need to decide the efficiency value before calling the other constructor.  For now just repeat the necessary instance variable assignments in the constructors you want to use for the rest of the lab.  If you have time at the end of the lab try to consolidate your various constructors using this().

 

  1. Add another private instance variable of type int for the year the car was manufactured, e.g. year, and a public setYear() method taking an int parameter to modify it from outside the class.  In practice we would modify all versions of the constructors to initialize and set year.  However, for now, just use setYear() after you create a new automobile instance to give that instance a year.  Also add a public method that resets the fuel efficiency called computeFuelEfficiency().  Based on the automobile's model, year, and mileage it will determine the expected fuel efficiency and assign it to the car.  Compute the expected fuel efficiency as follows:

 


Start by using
setFuelEfficiency(this.model) to set the car's efficiency to the value for that model.  Then, modify that value as needed for each of the above cases.

Does the order of the cases matter?  What fuel efficiency does a vehicle older than 5 years and with mileage between 60,000 and 100,000 have?  Try drawing a grid on paper with mileage on one axis and the car's age on the other to help.

 

  1. Compile and test the method of the previous step.  Be sure to come up with a test case for all branches of the statement to ensure you implemented it correctly.  Work out a few examples on paper and see if your code gives a matching answer.

 

  1. Add a constant PRIUS = "Prius" to your class if you haven't already.  Also add constants to your class called PRIUS_FUEL_EFFIC = 30.0 and PRIUS_BATTERY_EFFIC = 50.0.  Modify the drive method so that the first and last 5 miles of any trip by a Prius consumes fuel at the BATTERY_EFFIC rate and the rest of the trip uses fuel at the FUEL_EFFIC rate.  Make any other changes to help support this change.  Test your changes.  Again the change is only for Prius vehicles, not all models.

 

  1. Change the drive method for non-Prius models.  They should get 75% of that vehicle's (not the model's) fuel efficiency for the first and last 5 miles and the vehicle's usual fuel efficiency for the remainder of the trip.  Again, test the changes.

 

  1. Advanced Topic 5.2 describes the switch statement which can be used for some nested if else tests.  Which if any tests we have implemented in Automobile can be expressed using switch?

 

  1. Advanced Topic 5.3 describes the concept of an "enumerated type".  This is useful when there are only a small list of allowable values.  Can you see a way to use such types in this lab?  In the project?