|
|
|
Sponsored Link •
|
|
Advertisement
|
So what are class members good for?
In my opinion, the best mindset to cultivate when designing Java
programs is to think objects, objects, objects. Focus on designing
great objects, and think of classes primarily as blueprints for objects
-- the structure in which you define the instance variables and
instance methods that make up your well-designed objects. Besides that,
you can think of classes as providing a few special services that
objects can't provide, or can't provide as elegantly. Think of classes
as:
Utility methods
Methods that don't manipulate or use the state of an object or class I
call utility methods. Utility methods merely return some value (or
values) calculated solely from data passed to the method as parameters.
You should make such methods static and place them in the class most
closely related to the service the method provides.
An example of a utility method is the String copyValueOf(char[]
data) method of class String. This method produces
its output, a return value of type String, solely from its
input parameter, an array of chars. Because
copyValueOf() neither uses nor affects the state of any
object or class, it is a utility method. And, like all utility methods
should be, copyValueOf() is a class method.
So one of the main ways to use class methods is as utility methods -- methods that return output calculated solely from input parameters. Other uses of class methods involve class variables.
Class variables for data hiding
One of the fundamental precepts in object-oriented programming is
data hiding -- restricting access to data to minimize the
dependencies between the parts of a program. If a particular piece of
data has limited accessibility, that data can change without breaking
those portions of the program that can't access the data.
If, for example, an object is needed only by instances of a particular class, a reference to it can be stored in a private class variable. This gives all instances of this class handy access to that object -- the instances just use it directly -- but no other code anywhere else in the program can get at it. In a similar fashion, you can use package access and protected class variables to reduce the visibility of objects that need to be shared by all members of a package and subclasses.
Public class variables are a different story. If a public class variable isn't final, it is a global variable: that nasty construct that is the antithesis of data hiding. There is never any excuse for a public class variable, unless it is final.
Final public class variables, whether primitive type or object
reference, serve a useful purpose. Variables of primitive types or of
type String are simply constants, which in general help to
make programs more flexible (easier to change). Code that uses
constants is easier to change because you can change the constant value
in one place. Public final class variables of reference types allow you
to give global access to objects that are needed globally. For
example, System.in, System.out, and
System.err are public final class variables that give
global access to the standard input output and error streams.
Thus the main way to view class variables is as a mechanism to limit the accessibility of (meaning to hide) variables or objects. When you combine class methods with class variables, you can implement even more complicated access policies.
Using class methods with class variables
Aside from acting as utility methods, class methods can be used to
control access to objects stored in class variables -- in particular,
to control how the objects are created or managed. Two examples of this
kind of class method are the setSecurityManager() and
getSecurityManager() methods of class
System. The security manager for an application is an
object that, like the standard input, output, and error streams, is
needed in many different places. Unlike the standard I/O stream
objects, however, a reference to the security manager is not stored in
a public final class variable. The security manager object is stored in
a private class variable, and the set and get methods implement a
special access policy for the object.
Java's security model places a special restriction on the security
manager. Prior to Java 2 (aka JDK 1.2), an application
began its life with no security manager
(getSecurityManager() returned null). The
first call to setSecurityManager() established the
security manager, which thereafter was not allowed to change. Any
subsequent calls to setSecurityManager() would yield a
security exception. In Java 2, the application always starts out with a
security manager, but similar to the previous versions, the
setSecurityManager() method will allow you to
change the security manager one time, at the most.
The security manager provides a good example of how class methods can be used in conjunction with private class variables to implement a special access policy for objects referenced by the class variables. Aside from utility methods, think of class methods as the means to establish special access policies for object references and data stored in class variables.
|
Sponsored Links
|