CS 139 Algorithm Development
Lab12B: Method Overloading and More About Objects


Objectives:

Students will be able to:

Background:

Object Oriented programming switches the view of a program as a series of steps to a view of a program as an interaction between objects. You design the objects with what they should look like (instance variables, fields) and what behaviors they should have (methods). Then your driver will control how those objects interact in the world. In this version of the lab, you will be extending your Car class to do some new behaviors.

New Terms:

Materials:


Acknowledgment:    Gaddis, Programming Challenges 2, 4th edition


Part 1:  General Instructions:

  1. Setup your program environment by creating a new folder.

  2. Copy your Car and CarTester classes from the previous lab into the new directory.

Part 2: Beginning - Revisit your constructor:

  1. In your constructor, you probably used parameter names (for the model and year) that are different from the instance variable names. We are going to look at "shadowing" (see Gaddis 6.5 (Puzzle) or 6.7 (Watermelon)).

    Change the names of the two constructor parameters to the same name as the Car instance variables. The body of the constructor is now within the scope of both the parameters and the instance variables.

  2. Run your CarTester. Look in particular at the toString call after you call the constructor. What do you see?
    (No formal answer required, just think through what happened).

    Java uses the rule that when there are two identifiers with the same name in scope, the one with the most local scope (the parameter in this case) has precedence. The other (the instance variable in this case) is "shadowed" by the local variable.

    So the statement modelYear = modelYear; does not move the value from the parameter to the instance variable; rather it moves it from the parameter to the parameter.

  3. Inside of the class, the built-in reference variable "this" refers to the object that is executing the method (see Gaddis 9.8 (Puzzle) or 8.8 (Watermelon)). We solve the shadowing problem by referring to the instance variable as this.modelYear. Now the compiler knows that we are moving the data from the parameter to the instance variable. Change the assignment statements in the constructor to use this. as the name qualifier, then rerun your tester. Is everything okay?

  4. The this. qualifier should be used for any reference to instance variables, even though it's not generally required. It is good practice because it makes it clear in any method which variables are local to the method and which belong to the object itself.

    Change each of the references to instance variables in the Car methods to this.variableName .

Part 3: Overloading a constructor:

  1. Add to your Car class a color instance variable that is a String.

  2. Build a new constructor (also keep the original constructor) that takes in the same parameters as the first one plus color.

  3. In the original constructor, set color to the empty String, "";

  4. Test the new constructor in your tester by making a new car with a color argument filled in.

  5. Add color to your toString method. It should read ("A %s %d %s that is going %d mph", color, year, make, speed)

  6. Test the new Car constructor by creating a Car with color and displaying its toString() return value.

4 Refinement:

Instead of having the top speed built into the methods, wouldn't it be better to include it as an instance variable (instance variable) for that car?

  1. Add an instance variable for the top speed (bottom speed will always be assumed to be 0).

  2. Add another constructor which includes maxSpeed as well as the make, year, and color. This constructor should insure that the top speed value is > 0. If not, set the top speed to 150.

  3. For the other two constructors, add a statement to set the top speed to 150.
     
  4. Also add topSpeed to the toString method.

  5. Test your new constructor and retest the former constructors.

  6. Change your code for accelerate() to insure that it will respect the top speed limit. Test this change, making sure that you try to accelerate() each of your cars past the top speed and insure that the speed is cutoff at the appropriate place.

5 Exploring a no-args constructor:

At this point, you have no default constructor for your car class. As soon as you made the explicit value constructor for the original Car lab, the default was gone. Sometimes it is useful to have a default constructor in your class. (Gaddis - 6.4)

  1. Create another constructor that takes in no parameters. Set the attributes to your favorite type of car.
  2. Test your default constructor in your tester by instantiating a new Car with no parameters.

6 Exploring a copy constructor:

In some instances it is necessary to make a copy of a particular object. We can provide a copy constructor that will set the values of "this" object to the values of the passed object. Reference is Gaddis 8.6.

  1. Create a new constructor that accepts a Car object as its only parameter.

  2. Set the instance variables to the corresponding values of the Car parameter.

  3. Test by creating a new Car based on one of the other four cars you have created. accelerate() one, but not the other. Prove that they are different objects by seeing if their references are pointing to different objects.

7 Using two objects in a method - Equals

Many objects include an equals method. Equals compares two objects based on whatever criteria is appropriate. For example, we may decide two cars are the same if they have the same make and year irregardless of the color. See Gaddis 8.5 for an example of an equals method.

  1. Create a new method, equals, that takes in a single Car object and returns a boolean value.
  2. Create your method to return true if the year and make of this Car and the parameter Car are the same and false otherwise. When comparing makes, disregard the case of the make (Prius equals prius).
  3. Test your method by comparing two cars that are the same based on this criteria and two cars that are not.

8 OPTIONAL - Exploring a "factory" method:

Factory methods are methods that return an object of the given class. They differ from constructors in that the caller simply executes the method to get an object and all of the instantiation is done inside the method. You have seen a factory method if you ever used the getCurrencyFormat method in the NumberFormat class.

  1. Create a method, makeCar, that accepts the parameters for a car (it should include all of the attributes except speed) and returns a Car object.
  2. This method should be defined as "static" since we don't need to have a Car to be able to make a car. In other words, the makeCar method belongs to the class itself.
  3. Within this method, you should have a Car variable, and then instantiate a Car object passing in the parameters to the constructor.
  4. Return the Car object. (What is it that you are actually returning? )

Updated 11/11//2014 (rfg, nlh)