October 25, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Hiding Data within Object-Oriented Programming

  • July 29, 2004
  • By Matt Weisfeld
  • Send Email »
  • More Articles »

In our design, these two methods represent the public interface to the CheckingAccount class. These methods are the only way that an application can get access to the balance attribute. These types of methods are sometimes referred to as getters and setters, for obvious reasons. Some books combine the concept of getters and setters and call them mutator methods, or simply mutators. In any case, these getters and setters represent the way that access to an attribute is controlled. And object-oriented design is all about control.

Not all attributes will have both a getter and a setter. There are situations where you may want to allow a user the ability to inspect an attribute, but not change it—in effect read permission only. For example, let's assume that when we design our CheckingAccount class, we only want to allow outside applications to inspect balance and not change it. We could write the class as seen in Listing 3.

class CheckingAccount {
   private double balance = 0;
   private void setBalance(double bal) {
      balance = bal;
   };
   public double getBalance(){
      return balance;
   };
}

Listing 3: CheckingAccount.java with 'read only' access to balance

Notice now that setBalance() is designated as private.

private void setBalance(double bal);

   balance = bal;
};

This will prohibit an application from calling the setBalance() method, thus, in effect stopping the application from being able to change balance at all. Take a look at the code in Listing 4.

class Encapsulation {

   public static void main(String args[]) {
      System.out.println("Starting myEncapsulation...");
      CheckingAccount myAccount = new   CheckingAccount();
      myAccount.setBalance(40.00);
      System.out.println("Balance = " + myAccount.getBalance());
   }

}

Listing 4: Encapsulation.java with private access to setBalance()

Whereas this code worked perfectly when setBalance() was public, it now produces the following error:



Click here for a larger image.

Figure 2: Output with private setBalance().

You can see in Figure 2 that, when we attempt to compile this code, the compiler itself balks and does not allow the compilation to complete successfully. The following error is produced.

Encapsulation.java:8: setBalance(double) has private access in
CheckingAccount

                myAccount.setBalance(40.00);
                         ^

Thus, any application written with this CheckingAccount class will be unable to successfully call the setBalance() method. One of the design techniques that this illustrates is that, while all of the attributes of a class should be designated as private, not all the methods will necessarily be public.

What we have done with this design is limit the ability to set the value of balance to the class itself. In short, the setBalance() method is not part of the public interface of the class—it is now a private implementation of the CheckingAccount class.

Why would we even want to do this? Obviously, at some point the value of balance needs to be set. However, think about how an actual checking account really works. You, as a user of the account, have the ability to inspect your account balance, but you certainly can't set it directly. Doing this would be a major breach of security! So how can we model this in the design of our CheckingAccount class?

First, let's consider how you would actually add money to your account. The obvious answer to this question is that you would deposit money into your account. Thus, we can add a behavior called deposit() to the CheckingAccount class. Consider the UML class diagram in Figure 3.

Figure 3: UML Diagram for Checking Account Class with deposit() method

With this version of the CheckingAccount class, we now have made the class more like the real world—we make a deposit. The code that implements this class is found in Listing 5.

class CheckingAccount {
   private double balance = 0;
   private void setBalance(double bal) {
      balance = bal;
   };
   public double getBalance(){
      return balance;
   };
   public double deposit(double dep){
         setBalance(balance + dep);
      return balance;
   };
}

Listing 5: CheckingAccount.java with deposit() method

Here is where the private implementation of setBalance() comes into play. Notice that rather than changing the value of balance directly, the deposit() method actually uses the setBalance() method. Even though setBalance() is private, the deposit() method can call it successfully because they are both members of the same class.

In this case, our application actually makes a deposit by calling the deposit() method, as shown in Listing 6.

class Encapsulation {

   public static void main(String args[]) {
      System.out.println("Starting myEncapsulation...");
      CheckingAccount myAccount = new   CheckingAccount();
      myAccount.deposit(40.00);
      System.out.println("Balance = " + myAccount.getBalance());
   }

}

Listing 6: Encapsulation.java using deposit()





Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel