$24
Overview
The week we continue our study of Java by taking a closer look at classes and objects. The topics covered in this lab include creating classes, creating objects and creating methods and controlling access to class members.
It is assumed the JDK 8 or higher programming environment is properly installed and the associated readings for this week have been completed.
Submission requirements
Hands-on labs are designed for you to complete each week as a form of self-assessment. You do not need to submit your lab work for grading. However; you should post questions in the weekly questions area if you have any trouble or questions related to completing the lab. These labs will help prepare you for the graded assignments, therefore; it is highly recommended you successfully complete these exercises.
Objectives
The following objectives will be covered by successfully completing each exercise:
Create Java classes and construct objects from the classes
Assign member modifiers to control access within Java classes
Exercise 1 – Create Java classes and construct objects from the classes
Java classes can be thought of a blueprints that we can use to construct objects. We have already used constructors when we created an instance of the Scanner, String and other classes.
In this exercise we create a class representing a Point. The Point class will have a constructor, fields and methods. For example, a Point (in 2-dimensions) will have an x and y value. We won’t be plotting points yet. We will just be creating a Point class and calculating values that might be used in a Point class with methods.
a. Open your favorite text editor and Type (or copy and paste) the following Java
/*
File: TestPoint.java
Author: Dr. Robertson
Date: January 1, 2015
Purpose: This program constructs instances
of the Point class and uses
its methods
*/
1
public class Point {
private double x;
private double y;
// Constructor
public Point (double px, double py) {
x = px;
y = py;
}
Default constructor public Point () {
= 0.0;
= 0.0;
}
Setter methods
setX
public void setX(double px) {
x = px;
}
// setY()
public void setY(double py) {
y = py;
}
Getter methods
getX
public double getX() {
return x;
}
// getY
public double getY() {
return y;
}
Use Math method to get the distance
between 2 points
public double getDistance(Point p1, Point p2) { // delta x
double deltaX = Math.abs(p1.getX() - p2.getX()); // delta y
double deltaY = Math.abs(p1.getY() - p2.getY());
// Distance formula
double distance = Math.sqrt(deltaX*deltaX + deltaY*deltaY); return distance;
}
// toString method
public String toString() {
String str = "(" + x + ", " + y + ")";
return str;
}
2
}
Save the file as “Point.java” in a location of your choice.
To compile the file, type javac Point.java at the command prompt.
To test the Point class, you will need an additional class. These classes are often called Driver or Test classes and are used to construct instances of the class and call the methods. You create a class containing a main method. In the main method you construct an existing class and then call the methods. To create a test class for the Point class, open your favorite text editor and copy and paste the following code:
/*
File: TestPoint.java
Author: Dr. Robertson
Date: January 1, 2015
Purpose: This program constructs instances
of the Point class and uses
its methods
*/
public class TestPoint {
public static void main(String[] args) {
Construct a point with 1.0, 1.0 Point p1 = new Point(1.0,1.0);
Construct a default point
Point p2 = new Point();
Call the getter methods double p1X = p1.getX(); double p1Y = p1.getY();
Print results
System.out.println("p1 values from getX() getY() " + p1X + "," + p1Y);
double p2X = p2.getX();
double p2Y = p2.getY();
// Print results
System.out.println("p2 values from getX() getY() " + p2X + "," + p2Y);
// Call the Distance Method
double distance = p1.getDistance(p1,p2); // Print results
System.out.println("Distance between p1 and p2 is: " +
distance);
Change the XY value of P1
Using the setter method double newX = 2.0; double newY = 2.0;
3
p1.setX(newX);
p1.setY(newY);
Recalculate the Distance distance = p1.getDistance(p1,p2);
Print results
System.out.println("New Distance between p1 and p2 is: " +
distance);
Display the values using toString System.out.println(p1.toString()); System.out.println(p2.toString());
}
}
Save the file a TestPoint.java in the same directory as the Point.java file. Compile and then execute java TestPoint. Note, that you have previously compiled Point.java. If you hadn’t compiled Point.java, the TestPoint.java file would not find the class. The output will look similar to this:
As you analyze and experiment with the code, note the following:
The Point.java file contains 2 different constructors. The default constructor will assign x and y to 0.0. Classes can have multiple constructors. Designing constructors are often based on the data available or the specific application. You use constructors to create an instance (or object) of a class.
4
The x,y fields are Private. This means the values are encapsulated requiring the call to getX() or getY() to reveal the value. If you try to call p1.x or p1.y you will receive compile error. For example, if I added this code to the TestPoint.java:
System.out.println("p1.x is " + p1.x);
And then tried to recompile, an error message similar to the following would be received:
TestPoint.java:51: error: x has private access in Point
System.out.println("p1.x is " + p1.x);
Defining fields as private, is a good security practice demonstrates good object-oriented design. In most cases, you should declare fields as private in the classes you design.
Because the fields are private, we define getter methods called getX() and getY(). These methods allow for access to values of x and y as demonstrated in the following code:
double p2X = p2.getX(); double p2Y = p2.getY();
Setter methods are also used allowing the ability of the user to change the x, and y values of the Point. The following code demonstrates their use:
double newX = 2.0; double newY = 2.0; p1.setX(newX);
p1.setY(newY);
Notice, we took advantage of the static Math.abs() and Math.sqrt() methods in the Math class in the getDistance() method of the Point class. In most cases, You should use existing classes as opposed to reinventing the wheel.
Also, notice the toString() method returns the current x,y values of the point when called.
Now it is your turn. Try the following exercise:
Create a Java class named Point3D using your favorite text editor. Be sure you name the file
“Point3D.java”. Add code to the file in the main() method that will construct a 3D Point (x, y and z). You should have a default constructor located at (1.0,-1.0, -1.0) and another constructor that uses three double values for x, y and z. Provide a getDistance() method that returns the distance between two 3D points. Also, provide getter and setter methods for x, y and z. Create a toString() method that prints the values of x, y and z in the format (x,y,z). Finally create a TestPoint3D.java file to construct several points and demonstrate the use of all of the methods.
5
Exercise 2 - Assign member modifiers to control access within Java classes
Member modifiers are used to denote the access level for fields, methods and classes. Modifiers include public, private, protected and no modifier. Understanding the differences will take some practice and delving deeper into packages and sub-classes. Since we just have introduced objects, we will focus on private versus public for fields and methods at this time. Private methods and fields are only accessible by the class itself without encapsulation (e.g. getX() to return the x component in the Point class). Public methods and fields are accessible by all other classes.
To demonstrate this we will use the Point class from the previous class and modify the members to show the differences. We will also use the TestPoint class to demonstrate the impact of changing these modifiers.
Open up the Point.java file and copy it to PointAccess.java. Change the Y variable to public access and change the getDistance() method to private. When you change the name of the class, several other changes are required so the code will compile. The code changes are highlighted in yellow below.
/*
File: PointAccess.java
Author: Dr. Robertson
Date: January 1, 2015
Purpose: This program constructs instances
of the Point class and uses
its methods
*/
public class PointAccess {
private double x;
public double y;
// Constructor
public PointAccess (double px, double py) { x = px;
y = py;
}
Default constructor
public PointAccess () {
= 0.0;
= 0.0;
}
Setter methods
setX
public void setX(double px) {
x = px;
}
// setY()
public void setY(double py) {
y = py;
}
6
Getter methods
getX
public double getX() {
return x;
}
// getY
public double getY() {
return y;
}
Use Math method to get the distance
between 2 points
private double getDistance(PointAccess p1, PointAccess p2) { // delta x
double deltaX = Math.abs(p1.getX() - p2.getX()); // delta y
double deltaY = Math.abs(p1.getY() - p2.getY());
// Distance formula
double distance = Math.sqrt(deltaX*deltaX + deltaY*deltaY); return distance;
}
// toString method
public String toString() {
String str = "(" + x + ", " + y + ")";
return str;
}
}
Modify the TestPoint.java and copy it to TestPointAccess.java. The code changes required are shown below in yellow:
/*
File: TestPointAccess.java
Author: Dr. Robertson
Date: January 1, 2015
Purpose: This program constructs instances
of the Point class and uses
its methods
*/
public class TestPointAccess {
public static void main(String[] args) {
Construct a point with 1.0, 1.0 PointAccess p1 = new PointAccess(1.0,1.0);
Construct a default point
PointAccess p2 = new PointAccess();
7
Call the getter methods double p1X = p1.getX(); double p1Y = p1.getY();
Print results
System.out.println("p1 values from getX() getY() " + p1X + "," + p1Y);
double p2X = p2.getX();
double p2Y = p2.getY();
// Print results
System.out.println("p2 values from getX() getY() " + p2X + "," + p2Y);
// Call the Distance Method
double distance = p1.getDistance(p1,p2); // Print results
System.out.println("Distance between p1 and p2 is: " +
distance);
Change the XY value of P1
Using the setter method double newX = 2.0; double newY = 2.0; p1.setX(newX);
p1.setY(newY);
Recalculate the Distance distance = p1.getDistance(p1,p2);
Print results
System.out.println("New Distance between p1 and p2 is: " +
distance);
Display the values using toString System.out.println(p1.toString()); System.out.println(p2.toString());
}
}
Attempting to run this code, will result in an error as we are trying to call a private method of the PointAccess class from the TestPointAccess class.
8
d. Comment out those lines of code and recompile and run.
With the lines related to calling the private getDistance() method and associated print methods are commented out, the code compiles and runs. If you envision, methods will be used by other classes, you should not declare them private as they cannot be used by the other classes.
By changing the y field to public, we can now use p1.y to access the results directly. As mentioned in the reading this is not recommended. To demonstrate this functionality add the following code to the bottom of the TestPointAccess.java code:
9
Display the y values directly System.out.println("p1.y is " + p1.y); System.out.println("p2.y is " + p2.y);
After compiling and executing the the p1.y and p2.y field variables are directly accessible.
Now it is your turn. Try the following exercise:
Modify the Java class named Point3D to change the access to make the setter methods private. Try to call the setX(), setY() and setZ() methods from the TestPoint3D class and note the errors. Change the x, y and z fields to public access. Then attempt to print the p1.x, p1.y, p1.z, p2.x, p2.y and p2.z values directly as opposed to using the getter methods. You will need to comment out some code, to get past the compile errors related to the private methods.
10