Data Field Encapsulation
Tags: java, programming, learning, beginners
Published: 2024-06-03 19:14:18

Making data fields private protects data and makes the class easy to maintain. The data fields **radius** and **numberOfObjects** in the **CircleWithStaticMembers** class in **CircleWithStaticMembers.java** can be modified directly (e.g., **c1.radius = 5** or **CircleWithStaticMembers.numberOfObjects = 10**). This is not a good practice—for two reasons:

- First, data may be tampered with. For example, **numberOfObjects** is to count the number of objects created, but it may be mistakenly set to an arbitrary value (e.g., **CircleWithStaticMembers.numberOfObjects = 10**).
- Second, the class becomes difficult to maintain and vulnerable to bugs. Suppose you want to modify the **CircleWithStaticMembers** class to ensure that the radius is nonnegative after other programs have already used the class. You have to change not only the **CircleWithStaticMembers** class but also the programs that use it, because the clients may have modified the radius directly (e.g., **c1.radius = -5**).

To prevent direct modifications of data fields, you should declare the data fields private, using the **private** modifier. This is known as _data field encapsulation_.

A private data field cannot be accessed by an object from outside the class that defines the private field. However, a client often needs to retrieve and modify a data field. To make a private data field accessible, provide a _getter_ method to return its value. To enable a private data field to be updated, provide a _setter_ method to set a new value. A getter method is also referred to as an _accessor_ and a setter to a _mutator_.

A getter method has the following signature:

`public returnType getPropertyName()`

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

`public boolean isPropertyName()`

A setter method has the following signature:

`public void setPropertyName(dataType propertyValue)`

Let’s 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 below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfu364bntex065k6tcq7.png)

The new circle class, named **CircleWithPrivateDataFields**, is defined in program below:

```
package demo;

public class CircleWithPrivateDataFields {
	/** The radius of the circle */
	private double radius = 1;
	
	/** The number of objects created */
	private static int numberOfObjects = 0;
	
	/** Construct a circle with radius */
	public CircleWithPrivateDataFields() {
		numberOfObjects++;
	}
	
	/** Construct a circle with a specified radius */
	public CircleWithPrivateDataFields(double newRadius) {
		radius = newRadius;
		numberOfObjects++;
	}
	
	/** return radius */
	public double getRadius() {
		return radius;
	}
	
	/** Set a new radius */
	public void setRadius(double newRadius) {
		radius = (newRadius >= 0) ? newRadius : 0;
	}
	
	/** return numberOfObjects */
	public static int getNumberOfObjects() {
		return numberOfObjects;
	}
	
	/** Return the area of this circle */
	public double getArea() {
		return radius * radius * Math.PI;
	}
}

```

The **getRadius()** method (lines 22–24) returns the radius, and the **setRadius(newRadius)** method (line 27–29) sets a new radius for the object. If the new radius is negative, **0** is set as the radius for the object. Since these methods are the only ways to read and modify the radius, you have total control over how the **radius** property is accessed. If you have to change the implementation of these methods, you don’t need to change the client programs. This makes the class easy to maintain.

The program below gives a client program that uses the **Circle** class to create a **Circle** object and modifies the radius using the **setRadius** method.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vwg6wewlfxey9q7uh02.png)

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

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 **100** objects of the **Circle** class. Suppose you combined **TestCircleWithPrivateDataFields** and **Circle** into one class by moving the **main** method in **TestCircleWithPrivateDataFields** into **Circle**. To prevent data from being tampered with and to make the class easy to maintain, declare data fields private.