Creating Instance Variables, a Constructor, Accessors, and Mutators
Creating Instance Variables
Instance variables of an object acts as data containers within an object. The entire object state is represented by the values of its instance variables. Each instantiated object has its own copy of its classes' instance variables.
In the Fraction class:
-
Create a private instance variable of type
int
with the namenumerator
. -
Create a private instance variable of type
int
with the namedenominator
.
/** * An int representing the numerator of the fraction. */ private int numerator; /** * An int representing the denominator of the fraction. */ private int denominator;
Together, the numerator
and denominator
variables represent the state of a particular instance of a Fraction object. The visibility modifier is private
, meaning that only the Fraction class's methods have access to instance variables. The instance variables cannot be accessed outside the Fraction class by a different class.
Creating a Constructor
Constructors are invoked when a new object is created. They are used to initialized the object and set the instance variables. All classes must have at least one constructor.
In the Fraction class:
-
Create a public constructor that takes two parameters with the first parameter being an
int
namedn
, and the second parameter being anint
namedd
. These variables can be named whatever you want because, as input parameters to a method, they only exist within this method. -
Set the instance variable
numerator
equal to the input parametern
, and set the instance variabledenominator
equal to the input parameterd
.
Since you are able to name the input parameters to the constructor whatever you want, what would happen if you were to name them numerator
and denominator
? How would you be able to tell them apart from the instance variables (which are also named numerator
and denominator
).
The keyword this
when used within a class is a reference to the calling/host object. If you consider the following example, the parameters
passed into the constructor have the same name as the instance variables. So when the numerator
name is used within the constructor, the variable with the narrowest scope (in this case, the parameter passed to the constructor) takes precedence. In this case, the this
keyword must be used to differentiate between the parameters and instance variables.
/** * Constructs a new Fraction with a provided numerator and denominator * Precondition: denominator must be greater than zero * Postcondition: None * @param n the numerator of the new Fraction * @param d the denominator of the new Fraction * @return None */ public Fraction( int numerator, int denominator ) { //A Fraction cannot have a zero denominator. if (denominator == 0) throw new RuntimeException("Divide By Zero Exception"); else { //Use this keyword to assign value of the //argument to the private variables } }
Creating Accessors
Accessor (or getter) methods simply return the value of an object's instance
variables. The standard naming convention for an accessor in Java is get[VariableName]()
. In many cases, you may not want a user of
your class to access or even know about an instance variable's type or
value, but in most instances it is considered safe to provide accessors.
The return type of an accessor should be the type of the instance variable being accessed. In most cases it will simply consist of a single return statement.
/** * Retrieves the value of the numerator * Precondition: None * Postcondition: None * @param None * @return An int representing the numerator */ public int getNumerator() { //return numerator }
Creating Mutators
Mutator (or setter) methods change the values of an object's instance
variables. The standard naming convention for a mutator in Java is
set[VariableName]()
. As with accessors, providing mutators is
not always a good idea. Allowing a user to change certain instance
variables directly instead of letting the class control its own instance
variables may not be safe. Take for example, any class which keeps a
counter instance variable. If the counter is altered directly by a user, it
could ruin the state of an object.
For our Fraction class, we do not want the user to be able to change the numerator or denominator. We want the Fraction class to be immutable so we will not be writing mutators. But if we did for example, the form would be as follows:
/** * Sets the value of the numerator to the provided value * Precondition: None * Postcondition: None * @param n the value to which the numerator should be changed. * @return None */ public void setNumerator(int n) { this.numerator = n; }