For this particular problem, the Friend class can be kept simple
This is a good thing
The only information the Friend objects need to know is their
First Name
Last Name
Email Address
A constructor will be be needed that describes the setup for the Friend object
Assigning the values to the fields
The behaviours of the Friend class
A way to retrieve information from the Friend
A way to obtain a string representation of the Friend
A way to check if two Friend objects are equal
3.2.1. Setting Fields and Writing the Constructor
The constructor is a special method that is called automatically when an object of the class is created
Typically, setup related things that needs to happen for the object will be put in the constructor
In Python, the Friend class’ constructor and the creation and assigning of fields would look like the following
Remember, in Python self is used to refer to an instance of the class
1classFriend:23# Python --- Constructor and creating and setting fields4def__init__(self,first_name,last_name,email):5self.first_name=first_name6self.last_name=last_name7self.email=email
In Java, the class’ declaration of fields, constructor, and assigning values to the fields would look like the following
4/*** 5 * A plain old java class to keep track of friends. A Friend will know its first name, last name, and email address. 6 * This class provides getters/accessor methods for the attributes and can be checked for equality. 7 */ 8publicfinalclassFriend{ 910// Fields for the Friend Class11privatefinalStringfirstName;12privatefinalStringlastName;13privatefinalStringemail;1415/**16 * Create an instance of a Friend. The constructor takes the first name, last name, and email address of the Friend17 * to be created.18 *19 * @param firstName First name of the friend20 * @param lastName Last name of the friend21 * @param email Email address of the friend22 */23publicFriend(StringfirstName,StringlastName,Stringemail){24this.firstName=firstName;25this.lastName=lastName;26this.email=email;27}
The class is set to public so it can be accessed from any other class
The class is also set to final since, once an instance is created, it should not change — immutable
The fields are declared inside the class, but not within any method
They can be accessed by the whole class
To provide control over how the fields are accessed outside the class, they are set to private and final
private means the fields are not directly accessible outside the class
If they were assigned public, it would behave like Python
Although private, the values of the fields will ultimately be accessible, but through accessor methods
Discussed in more detail below
The Friend class will be made in such a way that the data is immutable — it doesn’t change once set
Thus, the fields are set to final so they can be set once and only once
Notice the java documentation (javadoc) comment is above the method
The constructor is public, has the same name as the class and file, and does not have a self parameter
Although Java does have a similar keyword — this
The this in the above example let’s Java resolve the ambiguity between the field and constructor parameter
this.firstName is the field where firstName is a local parameter for the constructor
It is not always necessary to use this in Java like how self is used in Python
Note
Two of the major differences seen between Python and Java is the use of the visibility modifiers
public/private and final. This was done to tell Java that instances of this class are to be immutable.
At first one may feel these extra keywords make the code too verbose, but consider that these extra keywords provide
the programmer with more explicit control over how their code is or is not used. Although these keywords are not
necessary, they are very powerful.
In Java, there is an equals method to define what it means for two objects to be equivalent
However, unlike Python, it does not overload the == operator
== for objects is reserved for checking if two things are literally the same object – aliases
Same memory address — it compares the memory addresses
equals is used to compare the content of the objects in some way
This is where equality between objects of the class is defined
Like toString, if not overridden, equals has the inherited behavior of checking sameness — ==
For the Friend class, two objects will be equal if all their fields match
52/**53 * Checks if two Friend objects are equal. Friend objects are considered equal if all their attributes are equal.54 *55 * @param o an "object" being compared to56 * @return True if the two objects are equal, false otherwise57 */58@Override59publicbooleanequals(Objecto){60// If o is actually in the same memory address of this61if(o==this){62returntrue;63}64// If o is null, then it's not equal65if(o==null){66returnfalse;67}68// if o and this are of different classes, they're not the equal69if(o.getClass()!=this.getClass()){70returnfalse;71}72// Cast o as a friend73Friendother=(Friend)o;74returnObjects.equals(this.firstName,other.firstName)&&75Objects.equals(this.lastName,other.lastName)&&76Objects.equals(this.email,other.email);77}
There is a lot going on in this method
First it checks if the Objecto is the actual thing being compared to — if(o==this)
If they are aliases for the same object
If they are, then obviously they are equal
It also check if it is null — if(o==null)
If it is null, then clearly this cannot be equal to o
It then checks if they are of the same class — if(o.getClass()!=this.getClass())
If they are not, then they are not equal
If the method gets to this point, it knows that o is of class Friend
It downcast the Object to class Friend
This allows for accessing the fields and methods from Friend
Lastly, it check if all the attributes are equal
Note
It is important to understand the difference between someObject==someOtherObject,
someObject.equals(someOtherObject), and Objects.equals(someObject,someOtherObject).
With someObject==someOtherObject, it checks if someObject and someOtherObject are referencing the same
object – aliases.
someObject.equals(someOtherObject) checks if someObject and someOtherObject are equivalent based on
someObject class’ equals method.
Objects.equals(someObject,someOtherObject) is the same as someObject.equals(someOtherObject), but makes the
equality check null safe. In other words, it first checks if both someObject and someOtherObject are null,
because then they are equal. Further, it won’t produce a NullPointerException if someObject happens to be
null.
Have a look at the relevant javadocs
The above example makes use of the third option to be safe around null. This is important because, based on the
way the class is written, it is possible to have the fields reference null. Consider creating a Friend
object with the following — newFriend(null,"Smith","bsmith@gmail.com"). This would make the field
firstName reference null, meaning a call to this.firstName.equals(other.firstName) would result in a null pointer
exception.
Below is an example of creating an instance of a Friend object based on the Friend class
It is a simple example where an instance is created, but that is all
1publicclassSomeClass{2publicstaticvoidmain(String[]args){34// Declare a Friend variable5// Create an instance of a Friend6// Assign the variable to reference the newly created Friend7FriendaFriend=newFriend("Bob","Smith","bsmith@gmail.com");8}9}
There is a bit going on:
Declare a variable of type Friend
FriendaFriend
Create an instance of a Friend object
newFriend("Bob","Smith","bsmith@gmail.com")
Assign the variable to reference the newly created object
The single equals is used for assignment — =
Note
Be mindful about what is actually stored in the aFriend variable. The object is not stored in the variable,
but a reference to the object is.
The aFriend variable holds a reference to an instance of a Friend object, not a Friend.
If the following two lines of code were run, two instances of a Friend would exist
This also means that the object that bFriend used to point to now has no reference to it
This would cause Java to delete the Jane Friend object
The Friend object that was referenced by bFriend now has no reference to it. The bFriend reference
variable refers to the same Friend the aFriend reference variable refers to. The aFriend and
bFriend reference variables are aliases for the same Friend object.
Warning
One may feel that the assignment works different between primitive types when compared to objects, but this is
wrong.
Remember what is stored in the variables — the contents of the variables are copied. The variables may store a
primitive type, or maybe a reference to an object. Either way, it’s the variable’s contents that are copied.