WebReference.com - Part 4 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (7/8)
[previous] [next] |
Beginning Java 2 SDK 1.4 Edition
Choosing Access Attributes
As you can see from the table of access attributes, all the classes we have defined so far have
had members that are freely accessible within the same package. This applies both to the methods and
the variables that were defined in the classes. This is not good object-oriented programming practice.
As we said in Chapter 1, one of the ideas behind objects is to keep the data members encapsulated so
they cannot be modified by all and sundry, even from other classes within the same package. On the other
hand, the methods in your classes generally need to be accessible. They provide the outside interface
to the class and define the set of operations that are possible with objects of the class. Therefore
in the majority of situations with simple classes (i.e. no sub-classes), you should be explicitly
specifying your class members as either public
or private
, rather than omitting
the access attributes.
Broadly, unless you have good reasons for declaring them otherwise, the variables in a public class
should be private
and the methods that will be called from outside the class should be
public
. Even where access to the values of the variables from outside a class is
necessary, you don't need to make them public
or leave them without an access attribute.
As we've just seen, you can provide access quite easily by adding a simple public
method
to return the value of a data member.
Of course, there are always exceptions:
For classes in a package that are not public, and therefore not accessible outside the package, it may sometimes be convenient to allow other classes in the package direct access to the data members.
If you have data members that have been specified as
final
so that their values are fixed, and they are likely to be useful outside the class, you might as well declare them to bepublic
.You may well have methods in a class that are only intended to be used internally by other methods in the class. In this case you should specify these as
private
.In a class like the standard class,
Math
, which is just a convenient container for utility functions and standard data values, you will want to make everythingpublic
.
All of this applies to simple classes. We will see in the next chapter, when we will be looking at sub-classes, that there are some further aspects of class structure that you must take into account.
Using a Package and Access Attributes
Let's put together an example that uses a package that we will create. We could put the
Point
and Line
classes that we defined earlier in a package we could call
Geometry
. We can then write a program that will import these classes and test them.
Try It Out--Packaging Up the Line and Point Classes
The source and .class
files for each class in the package must be in a directory with
the name Geometry
. Remember that you need to ensure the path to the directory (or
directories if you are storing .class
files separately) Geometry
appears in
the CLASSPATH
environment variable setting before you try compile or use either of these
two classes. You can do this by specifying the -classpath
option when you run the compiler
or the interpreter.
To include the class Point
in the package, the code in Point.java
will be:
package Geometry;
public class Point {
// Create a point from its coordinates
public Point(double xVal, double yVal) {
x = xVal;
y = yVal;
}
// Create a Point from an existing Point object
public Point(final Point aPoint) {
x = aPoint.x;
y = aPoint.y;
}
// Move a point
public void move(double xDelta, double yDelta) {
// Parameter values are increments to the current coordinates
x += xDelta;
y += yDelta;
}
// Calculate the distance to another point
public double distance(final Point aPoint) {
return Math.sqrt((x--aPoint.x)*(x--aPoint.x)+(y--aPoint.y)*(y--aPoint.y));
}
// Convert a point to a string
public String toString() {
return Double.toString(x) + ", " + y; // As "x, y"
}
// Retrieve the x coordinate
public double getX() {
return x;
}
// Retrieve the y coordinate
public double getY() {
return y;
}
// Set the x coordinate
public void setX(double inputX) {
x = inputX;
}
// Set the y coordinate
public void setY(double inputY) {
y = inputY;
}
// Coordinates of the point
private double x;
private double y;
}
Note that we have added the getX()
, getY()
, setX()
and
setY()
methods to the class to make the private data members accessible.
The Line
class also needs to be amended to make the methods public and to declare
the class as public
. We also need to change its intersects()
method so that it
can access the private data members of Point
objects using the set...()
and get...()
methods in the Point
class. The code in Line.java
,
with changes highlighted, will be:
package Geometry;
public class Line {
// Create a line from two points
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}
// Create a line from two coordinate pairs
public Line(double xStart, double yStart, double xEnd, double yEnd) {
start = new Point(xStart, yStart); // Create the start point
end = new Point(xEnd, yEnd); // Create the end point
}
// Calculate the length of a line
public double length() {
return start.distance(end); // Use the method from the Point class
}
// Return a point as the intersection of two lines -- called from a Line object
public Point intersects(final Line line1) {
Point localPoint = new Point(0, 0);
double num =(this.end.getY()--this.start.getY())
* (this.start.getX()Âline1.start.getX())
- (this.end.getX()--this.start.getX())
* (this.start.getY()--line1.start.getY());
double denom = (this.end.getY()--this.start.getY())
* (line1.end.getX()--line1.start.getX())
- (this.end.getX()--this.start.getX())
* (line1.end.getY()--line1.start.getY());
localPoint.setX(line1.start.getX() + (line1.end.getX()--
line1.start.getX())*num/denom);
localPoint.setY(line1.start.getY() + (line1.end.getY()--
line1.start.getY())*num/denom);
return localPoint;
}
// Convert a line to a string
public String toString() {
return "(" + start+ "):(" + end + ")"; // As "(start):(end)"
} // that is, "(x1, y1):(x2, y2)"
// Data members
Point start; // Start point of line
Point end; // End point of line
}
Here we have left the data members without an access attribute, so they are accessible from the
Point
class, but not from classes outside the Geometry
package.
How It Works
The package statement at the beginning of each source file defines the package to which the class
belongs. Remember, you still have to save it in the correct directory, Geometry
. Without
the public
attribute, the classes would not be available to classes outside the
Geometry
package.
Since we have declared the data members in the class Point
as private
, they
will not be accessible directly. We have added the methods getX()
, getY()
,
setX()
, and setY()
to the Point
class to make the values
accessible to any class that needs them.
The Line
class hasn't been updated since our first example, so we first have to sort
out the access attributes. The two instance variables are declared as before, without any access attribute,
so they can be accessed from within the package but not from classes outside the package. This is an
instance where exposing the data members within the package is very convenient, and we can do it without
exposing the data members to any classes using the package. And we have updated the intersects()
method to reflect the changes in accessibility made to the members of the Point
class.
We can now write the program that is going to import and use the package that we have just created.
[previous] [next] |
Created: July 29, 2002
Revised: July 29, 2002
URL: https://webreference.com/programming/java/beginning/chap5/4/7.html