Introduction
What are Classes and Objects?
Classes are simply blueprints that define how to create and use an Object.
First, Classes can contain public or private instance variables that an Object and an Object’s methods can use. If the instance variable is public the user can access it outside of the Class, if it is private only methods and Objects in the class can access and use it. A Class also contains methods that can be called either statically (without the use of an Object), such as methods within the Math class, or non-statically with the use of an initialized Object.
How to Initialize Objects
At this point you have already done a few Object initializations. For example, the initialization of a Scanner Object shown below.
Scanner scnr = new Scanner(System.in);
The beginning step of Object initialization is like variable initializations we have seen before:
Datatype variableName =
In the Scanner shown above, the Datatype is of type Scanner and variableName is scnr.
The next steps are where Objects become unique.
The first difference is the use of the new keyword. This tells the program that we want to allocate memory for an Object to exist in.
The next part of the statement is the most important part, this is the Object Constructor. The Constructor is a special method that defines certain aspects of an Object upon initialization.
Remember that a Class can be thought of as a blueprint. Think of a Constructor as a builder inside of a Class that is in charge of actually building an Object.
Constructors often accept arguments as input to initialize instance variables. Just like other methods Constructors can have anywhere from 0 to infinite arguments. Also like methods, for every argument you have in the Constructor’s parameters, you must pass as an argument in the Constructor call.
Constructors are unique in that the name of the Constructor is exactly the same name as the Class. As shown in the Class below, the Class name is “Dog”, and the Constructor name is also “Dog”. YES, capitalization does matter!
Let’s look at an example of a Constructor.
Here is a class called Dog.
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Dog {
//These are instance variables
private String name;
private String breed;
private int age;
//This is the Constructor
public Dog(String name, String breed, int age){
this.name = name;
this.breed = breed;
this.age = age;
}
}
Here the Constructor is taking a String for a name of a dog, another String for a breed of a dog and finally an int for the age of a dog. The goal of this Constructor is to initialize the instance variables. The initialization of these variables can be seen in the Constructors body.
Notice that the instance variables have the same name as the Constructor arguments. Here a new keyword can be seen, the this keyword. The this keyword can be used to reference a current Object. It can also be used to avoid naming conflicts. In this case, since the instance variables and the Constructor arguments have the same name, the this keyword has to be used. In the Constructors body, the this keyword variables (i.e. this.name), represent the instance variables. Whereas the other variables (i.e. name) are the variable names of the arguments passed to the Constructor.
Variables Review
Just a quick review, remember there are two common access modifiers for variables in a Class: public and private. Public variables are visible and modifiable by anyone. Private are visible and modifiable only by you (within the Class). Unless you are using Mutators and Accessors.
Mutators and Accessors
Mutators and Accessors are often called setters and getters respectively. They are public methods that allow the user to Mutate, or Access, the values of private or public instance variables. One of the most important aspects of Mutators and Accessors is the ability to limit how the user sees and changes your variables.
Mutator
A Mutator, often called a setter, is a public method that allows the user to change the value stored in a variable. Setters are typically public methods that return nothing. They are commonly named in the style set/*Variable Name*/ and take an input that is of the same type as the variable being modified. For example, here is a sample setter for the above Dog Class to change the value stored in the name variable.
Accessor
An Accessor, or often called a getter, is a public method that allows the user to access information from an instance variable. Almost all getters will be public methods that return a datatype of the same type as the variable being accessed. A typical naming convention for getters is get/*Variable Name*/, and takes no variables as an input. For example, here is a getter for the above Dog Class to see what the current value of the name variable is.
Initializing an Object and Using Methods
Initializing Objects
Below is an example of how to call a Constructor and make an Object with the Dog class.
Like stated earlier, the initialization is similar to that of a Scanner Object. In this case, The datatype is Dog and variable name is sampson. On the right side of the assignment operator, the Constructor is being called with the arguments it is asking for. More generally, an Object initialization can be shown as below.
Calling Methods with Objects
Once an Object is created, methods can be called to do all sorts of things, such as change instance variables.
Methods that are non-static are called with an Object. Shown below is a way to call a method with an Object along with a sample output.
The syntax for calling an Object is the Object’s name followed by a ‘.’ and then the method name.
One of the advantages of Objects is reusable code. As shown below, two different Objects are initialized but have the same methods called. Since the instance variables of each Object are different, this causes different results with the same method.
ZyLabs Assignment
In this assignment, you are given two files. The goal is to finish a Class’s Constructor, Accessors, Mutators, methods and test your code.
The details of the files are as follows:
-
CarMain.java
This file contains your main method (public static void main(String[] args)
), which also means it is an entry point into your program. Looking through this file, you will see a number of methods designed to help you test your code. It is very common practice that for every method you write, you write a secondary method to test it. -
Car.java
This is the heart of your program logic. You will code all of the methods and the Constructor in this class. This Class stores information about a car in its instance variables. The variables include a cars’ year, model, miles and fuel tank level. Since this is the majority of the coding, let’s start here! Select the file Car.java in the drop down.
Part 1: Car’s Constructor
In part 1, you are going to write the Constructor body for the Car Class. This will initialize the instance variables. The instance variables have been provided for you. Notice that the instance variables and arguments of the Constructor have the same variable names. How can you distinguish between these variables?
Part 2: getYear(), getModel(), getMiles(), getFuelTankLevel()
In part 2, you will finish writing the Accessors for each of the instance variables. Return the information for each respective instance variable.
Testing getYear(), getModel(), getMiles(), getFuelTankLevel()
When you run the program, it will automatically test the method by calling gettersTests(). You should find that method in CarMain.java. You should add your own tests, as we only have a limited amount of tests.
Part 3: addMiles(int milesToAdd)
The addMiles method is a method that will add to the current amount of miles already driven by a car. The miles instance variable holds the total amount of miles for a given car. For example, with the following code the miles variable for the car should end up being 200,150.
Testing addMiles(int milesToAdd)
There is a prewritten method called addMilesTests() method found in CarMain.java. You should add your own tests, as we only have a limited amount of tests. Think about what happens if addMiles is called more than once on a car?
Part 4: isFuelTankEmpty()
This method returns true or false based on if a given cars fuel tank level is 0.
- Hint: Which instance variable can give information on a fuel tank level?
Testing isFuelTankEmpty()
After writing this method check the method isFuelTankEmptyTests() in CarMain.java. There are prewritten test here. Make sure to add your own tests as well.
Part 5: milesToFuelLevel(int miles)
For this next method, you will write a conversion from miles to fuel level percentage. Since the fuelTankLevel variable represents a percentage, you will need to convert accordingly. For this method, assume that every car fuel tank has a maximum capacity of 400 miles. Return a ratio between miles and the fuel tank capacity as a percentage. (i.e. 62.5)
Testing milesToFuelLevel(int miles)
After writing this method check the method milesToFuelLevelTests() in CarMain.java. There are prewritten test here. Make sure to check if you are returning a percentage or a decimal representation.
Part 6: modifyFuelTankLevel(int miles)
For this method, you will write a method that changes a cars fuel tank level depending on the amount of miles inputted. Only change the fuel tank level if the fuel tank is not empty. If the miles inputted causes the fuel tank level to be negative, make the fuel tank level 0.
- Hint: What previous methods could help with this?
Testing modifyFuelTankLevel(int miles)
After writing this method check the method modifyFuelTankLevelTests() in CarMain.java. Make sure to add your own tests. If a fuel tank becomes negative is it set appropriately? Do your previous methods reflect the same information?
Part 7: drive(int miles)
For the last part of this assignment, you will write a that method “drives” a car. This method returns a string with a status of either the cars total mileage and fuel tank level, or if the fuel tank is empty. This method will also change a cars miles and fuel tank level. For example, calling drive with an input of 150, with a car that is a 2019 Honda CRV with 11,000 miles and a fuel tank level of 100%, will result in the following output.
The 2019 Honda CRV drove 150 miles, for a total mileage of 11150 and a fuel tank level of 62.5%.
If the Car Object’s fuel tank level is empty, then the following would be outputted.
The 2019 Honda CRV's fuel tank is empty!
- Hint: Take a look at the previous written methods. Could these help?
Testing drive(int miles)
Since this method is returning two different strings depending on a cars instance variables, it would be best to test for each string separately. For example, first write the code for if a cars fuel tank is empty. Is it returning the correct string and format? Next, write the code for a fuel tank that is not empty. Is this string returned correctly?