Operating on Class Variables with Class Methods


Just as it is bad form to expose instance variables of your objects directly to prying clients, it is also bad form to expose class variables publicly. The notable exception is the class constant idiombut there are even good reasons to avoid using class constants that you will learn in Lesson 5.

In addition to being able to use class methods for utility purposes, you can use class methods to operate on static data.

The CourseSession method testCount accesses the count class variable directly. Change the test code to ask for the count by making a class method call.

 public void testCount() {    CourseSession.count = 0;    createCourseSession();    assertEquals(1, CourseSession.getCount());    createCourseSession();    assertEquals(2, CourseSession.getCount()); } 

Then add a class method to CourseSession that returns the class variable count.

 static int getCount() {    return count; } 

Class methods can access class variables directly. You should not specify the class name when accessing a class variable from a class method.

The Java VM creates no instances of CourseSession as a result of calling the class method. This means that class methods on CourseSession may not access any of the instance variables that CourseSession defines, such as department or students.

The test method still refers directly to the count class variable, however, since you need it initialized each time the test is run:

 public void testCount() {    CourseSession.count = 0;    ... 

Change the code in CourseSessionTest to make a static message send to reset the count:

 public void testCount() {    CourseSession.resetCount();    createCourseSession();    assertEquals(1, CourseSession.getCount());    createCourseSession();    assertEquals(2, CourseSession.getCount()); } 

Add the resetCount method to CourseSession and make the count class variable private:

 public class CourseSession {    // ...    private static int count;    // ...    static void resetCount() {       count = 0;    }     static int getCount() {      return count;    }    // ... 

Making the count variable private will point out (when you recompile) any other client code that directly accesses it.

The testCount method, which documents how a client should use the Course-Session class, is now complete and clean. But the CourseSession class itself still accesses the class variable directly in its constructor. Instead of accessing static data directly from a member (an instance-side constructor, field, or method), a better approach is to create a class method that you call from the instance side. This is a form of encapsulation that will give you greater control over what happens to the class variable.

Change the CourseSession constructor to send the incrementCount message instead of accessing the class variable directly:

 public CourseSession(String department, String number, Date startDate) {    this.department = department;    this.number = number;    this.startDate = startDate;    CourseSession.incrementCount(); } 

Then add a class method to CourseSession that increments the count. Declare this method as private to prevent other classes from incrementing the counter, which could compromise its integrity:

 private static void incrementCount() {    count = count + 1; } 

It is possible to access a class method or variable from the instance side of a class without specifying the class name. As an example, you could change the constructor code to the following:

 public CourseSession(String department, String number, Date startDate) {    this.department = department;    this.number = number;    this.startDate = startDate;    incrementCount(); // don't do this! } 

Even though it will work, avoid doing this. Accessing class methods without using the class name introduces unnecessary confusion in your code and is considered bad form. Is incrementCount a class method or an instance method? Since it's not possible to tell from looking at the code in the CourseSession constructor alone, the intent is not clear. The expectation that a method is an instance method when it is in reality a class method can lead to some interesting problems.

Scope a class method call with the class name when invoking the class method from anywhere but another class method on the same class.




Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

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