WebReference.com - Part 4 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (7/8) | WebReference

WebReference.com - Part 4 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (7/8)

To page 1To page 2To page 3To page 4To page 5To page 6current pageTo page 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:

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.


To page 1To page 2To page 3To page 4To page 5To page 6current pageTo page 8
[previous] [next]

Created: July 29, 2002
Revised: July 29, 2002


URL: https://webreference.com/programming/java/beginning/chap5/4/7.html