7.8. Data Field Encapsulation

 
[Page 229 ( continued )]

The data fields radius and numberOfObjects in the Circle2 class in Listing 7.2 can be modified directly (e.g., myCircle.radius = 5 or Circle2.numberOfObjects = 10 ). This is not a good practice for two reasons:

  • First, data may be tampered. For example, numberOfObjects is to count the number of objects created, but it may be set to an arbitrary value (e.g., Circle2. numberOfObjects = 10 ).

  • Second, it makes the class difficult to maintain and vulnerable to bugs . Suppose you want to modify the Circle2 class to ensure that the radius is non-negative after other programs have already used the class. You have to change not only the Circle2 class, but also the programs that use the Circle2 class. Such programs are often referred to as clients . This is because the clients may have modified the radius directly (e.g., myCircle.radius = -5 ).


    [Page 230]

To prevent direct modifications of properties, you should declare the field private, using the private modifier. This is known as data field encapsulation .

A private data field cannot be accessed by an object through a direct reference outside the class that defines the private field. But often a client needs to retrieve and modify a data field. To make a private data field accessible, provide a get method to return the value of the data field. To enable a private data field to be updated, provide a set method to set a new value.

Note

Colloquially, a get method is referred to as a getter (or accessor ), and a set method is referred to as a setter (or mutator ).


A get method has the following signature:

   public   returnType get  PropertyName  () 

If the returnType is boolean , the get method should be defined as follows by convention:

   public boolean   is  PropertyName  () 

A set method has the following signature:

   public void   set  PropertyName(dataType propertyValue  ) 

Let us create a new circle class with a private data field radius and its associated accessor and mutator methods . The class diagram is shown in Figure 7.15. The new circle class, named Circle3 , is declared in Listing 7.5.

Figure 7.15. The Circle class encapsulates circle properties and provides get/set and other methods.

Listing 7.5. Circle3.java
(This item is displayed on pages 230 - 231 in the print version)
 1   public class   Circle3 { 2  /** The radius of the circle */  3    private double   radius =   1   ;  4 5  /** The number of the objects created */  6    private static int   numberOfObjects =     ;  7 8  /** Construct a circle with radius 1 */  9   public   Circle3() { 10 numberOfObjects++; 11 } 

[Page 231]
 12 13  /** Construct a circle with a specified radius */  14   public   Circle3(   double   newRadius) { 15 radius = newRadius; 16 numberOfObjects++; 17 } 18 19  /** Return radius */  20    public double   getRadius()  { 21   return   radius; 22 } 23 24  /** Set a new radius */  25    public void   setRadius(   double   newRadius)  { 26 radius = (newRadius >=     ) ? newRadius :     ; 27 } 28 29  /** Return numberOfObjects */  30    public static int   getNumberOfObjects()  { 31   return   numberOfObjects; 32 } 33 34  /** Return the area of this circle */  35   public double   getArea() { 36   return   radius * radius * Math.PI; 37 } 38 } 

The getRadius() method (lines 20 “22) returns the radius, and the setRadius(newRadius) method (lines 25 “27) sets a new radius into the object. If the new radius is negative, is set to the radius in the object. Since these methods are the only ways to read and modify radius, you have total control over how the radius property is accessed. If you have to change the implementation of these methods, you need not change the client programs. This makes the class easy to maintain.

Here is a client program that uses the Circle3 class to create a Circle3 object and modifies the radius using the setRadius method.

 1  // TestCircle3.java: Demonstrate private modifier  2   public class   TestCircle3 { 3  /** Main method */  4   public static void   main(String[] args) { 5  // Create a Circle with radius 5.0  6 Circle myCircle =   new   Circle(   5.0   ); 7 System.out.println(   "The area of the circle of radius "   8 +  myCircle.getRadius()  +   " is "   +  myCircle.getArea()  ); 9 10  // Increase myCircle's radius by 10%  11 myCircle.setRadius(myCircle.getRadius() *   1.1   ); 12 System.out.println(   "The area of the circle of radius "   13 +  myCircle.getRadius()  +   " is "   +  myCircle.getArea()  ); 14 } 15 } 

The data field radius is declared private. Private data can only be accessed within their defining class. You cannot use myCircle.radius in the client program. A compilation error would occur if you attempted to access private data from a client.


[Page 232]

Since numberOfObjects is private, it cannot be modified. This prevents tampering. For example, the user cannot set numberOfObjects to 100 . The only way to make it 100 is to create one hundred objects of the Circle3 class.

Suppose you combined TestCircle3 and Circle3 into one class by moving the main method in TestCircle3 into Circle3 . Could you use myCircle.radius in the main method? See Review Question 7.15 for the answer.

Note

When you compile TestCircle3.java , the Java compiler automatically compiles Circle3.java if it has not been compiled since the last change.


Tip

To prevent data from being tampered with and to make the class easy to maintain, most of the data fields in this book will be private.


 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net