Lab 3: Writing a Class¶
In this lab, you will implement a Car class that represents a car.
You will learn about non-static attributes and methods.
And you will gain experience creating and using objects.
Learning Objectives¶
After completing this lab, you should be able to:
- Interpret a UML class diagram and stub out the corresponding code.
- Implement constructors, accessors, mutators, equals, and toString.
- Write a test program that calls non-static methods of another class.
Step 1. Getting Started¶
Do the following steps in VS Code:
- Create a
lab03folder under yoursrc/labsfolder. - Add two new files:
Car.javaandMain.java. - Write the
packageandpublic classstatements. - Write a Javadoc comment with your name and date.
When finished, your Car.java and Main.java should look like this:

Step 2. UML Class Diagram¶
Based on the diagram below, declare each attribute and write a stub for each method.
Do not implement any methods yet, but make the code compile.
For example, if a method returns a String, write return ""; as a stub (placeholder).
Show your code to the instructor or TA before proceeding to the next step.
classDiagram
class Car {
- make: String
- speed: double
- year: int
+ Car(make: String, year: int)
+ getMake() String
+ getSpeed() double
+ getYear() int
+ accelerate() String
+ brake()
+ equals(obj: Object) boolean
+ toString() String
}
Note
The brake() method is void (does not return a value).
The word void is usually omitted in UML class diagrams.
Step 3. Constructor, Getters¶
The purpose of a constructor is to initialize the attributes of this object.
Notice the Car class has three attributes: make, speed, and year.
The constructor has two parameters: make and year.
Use the parameters to initialize this object's make and year.
Initialize this object's speed to zero.
Then write the Javadoc comment for the constructor.
Note
When writing documentation for constructors, do not use the word create.
Constructors do not "create" objects; the new operator creates an object.
Once an object has been created, the constructor is called to initialize the object.
The purpose of a getter method is to return the current value of an attribute.
Notice that the attributes are private, meaning they can be accessed only in the Car class.
Other classes, like Main, will need to use the public getters to access the attributes.
Implement each getter by returning the corresponding attribute.
Javadoc comments are not required for most getter methods. However, a Javadoc comment is required if a getter does more than simply return an attribute.
Step 4. Test the Constructor¶
Before implementing the other methods in Car.java, let's make sure the constructor and getter methods work correctly.
Open Main.java and define a main method.
Tip
In VS Code, you can type the word main inside the class, press Ctrl+Space (shortcut for "Trigger suggestion"), and press Enter.
That will generate the code for main for you.
However, you should memorize how to write a main method on your own,
so that you will be able to do so on a written exam, without assistance from VS Code.
Write a Javadoc comment for main, for example:
/**
* Test the Car class.
*
* @param args command-line arguments
*/
Then add the following code to main:
- Create two
Carobjects.- Each car should have a different make and year.
- Write
System.out.println()statements that show the attributes of car:getMake()should return the make you chose.getSpeed()should return zero (at this point).getYear()should return the year you chose.- You should have six
printlnstatements in total (3 for each car).
- Write one more
System.out.println();in the middle to separate the two cars.
Run the Main program by clicking the button or pressing F5.
The output should look something like:
Car #1's make: Nissan
Car #1's year: 2003
Car #1's speed: 0.0
Car #2's make: Tesla
Car #2's year: 2025
Car #2's speed: 0.0
Step 5. Accelerate and Brake¶
The accelerate() method increases the current speed of the car by 5 miles per hour.
After increasing the speed, accelerate() returns a string describing the change.
Use the format "15.0 + 5.0 = 20.0" where 15.0 is the old speed and 20.0 is the new speed.
Note
The String.format() method is useful for formatting double values.
For example, you can format the speed values to one decimal place as follows:
return String.format("%.1f + 5.0 = %.1f", speed - 5, speed);
%.1f in the format string is replaced by an argument.
So the first %.1f is the argument speed - 5, and the second %.1f is the argument speed.
Your code must not allow the speed to increase above 150 miles per hour.
If the speed is already 150, and accelerate() is called, the speed should remain 150.
In that case, the method should return the string "150.0 + 0.0 = 150.0".
The brake() method should decrease the current speed by 5 miles per hour.
Your code must not allow the speed to decrease below 0 miles per hour.
Notice the brake() method is void, which means no value is returned.
Write Javadoc comments for accelerate() and brake() before moving on to the next step.
Step 6. Test Driving the Car¶
Add the following code to Main:
- Call
System.out.println();to output a blank line.- Doing so will separate Step 6's output from Step 4's output.
- Call the
accelerate()method of the first car object.- Print the value returned from
accelerate(). - Call
getSpeed(), and print the result.
- Print the value returned from
- Call the
brake()method of the first car object.- Call
getSpeed(), and print the result.
- Call
The output for this step should look something like:
0.0 + 5.0 = 5.0
Car #1's speed: 5.0
Car #1's speed: 0.0
Step 7. The equals() method¶
The purpose of the equals() method is to determine if two objects are equivalent.
Replace your equals() method with the following partial solution:
@Override
public boolean equals(Object obj) {
if (obj instanceof Car) {
Car car = (Car) obj;
return true; // TODO compare make and year
}
return false;
}
The above code:
- Overrides the default implementation of
equals().- By default,
equals()returns true ifthisandobjare the same object.
- By default,
- Checks if
obj, which can be any type of object, is actually aCarobject.- If not, then
equals()returns false at the end by default.
- If not, then
- Declares a
Carvariable namedcarto reference the same object asobj.
Finish the method by replacing the word true with an expression that determines whether car has the same make and year as this object.
In other words, does car.make equal this.make, and does car.year equal this.year?
Warning
In Java, comparing strings using the == operator does not work.
You must call one string's equals() method and pass the other string as the argument.
Test your equals() method by adding the following code to Main:
- Call
System.out.println();to output a blank line. - Create a third
Carobject with the same make and year as the firstCarobject. - Add the following two lines:
System.out.println("Car #1 equals Car #2: " + car1.equals(car2)); System.out.println("Car #1 equals Car #3: " + car1.equals(car3));
The first line should output false, because the two cars are different.
The second line should output true, because the two cars have the same make and year.
Step 8: The toString() method¶
The purpose of the toString() method is to return a string that represents the object.
Replace your toString() method with the provided solution:
@Override
public String toString() {
return String.format("A %d %s that is going %.1f mph",
year, make, speed);
}
The above code:
- Overrides the default implementation of
toString().- By default,
toString()returns the class name and the memory location of the object. For example,"labs.lab03.Car@5b6f7412".
- By default,
- Uses the
String.format()method to build a string based on the object's attributes.
Note
Javadoc comments are not required for @Override methods, because the
documentation is already defined by the default implementation.
In VS Code, you can hover the mouse over a method's name to see the documentation.
Test your toString() method by adding the following code to Main:
- Call
System.out.println();to output a blank line. - Call the
accelerate()method:- One time for the first car.
- Two times for the second car.
- Three times for the third car.
- Write
System.out.println()statements that print each of the car objects.- You don't have to call the
toString()method.System.out.println(car1)will automatically call thetoString()method ofcar1.
- You don't have to call the
The output should look something like:
A 2003 Nissan that is going 5.0 mph
A 2025 Tesla that is going 10.0 mph
A 2003 Nissan that is going 15.0 mph
Step 9. Review and Submit¶
Your final program should call println() 18 times.
Therefore, you should have 18 lines of output (including 4 blank lines).
If not, double check that you completed the following steps:
- Step 4: output 7 lines
- Step 6: output 4 lines
- Step 7: output 3 lines
- Step 8: output 4 lines
Tip
You will refer back to this code in a future lab.
To make the code easier to remember, add the bullets above as comments to Main.java.
For example:
// Step 8: output 4 lines
System.out.println();
car1.accelerate();
car2.accelerate();
car2.accelerate();
...
Submit both Car.java and Main.java to Gradescope.
Points will be allocated as follows:
| Criterion | Points | Details |
|---|---|---|
| Compile | 0 pts | Success Required |
| CompileOfficialTests | 0 pts | Success Required |
| Style | 2 pts | Partial Credit Possible |
| OfficialTests | 8 pts | Partial Credit Possible |