Previous | Table of Contents | Next |
14.3.3.2. Global Variables?
Earlier we said that Java does not support global variables. In a sense, though, Circle.num_circles behaves just like one. What is different from a global variable in C is that there is no possibility of name conflicts. If we use some other class with a class variable named num_circles, there wont be a collision between these two global variables, because they must both be referred to by their class names. Since each class variable must be part of a class and must be referred to with its class name, each has a unique name. Furthermore, each class has a unique name because, as we saw in the section How Java Differs from C, it is part of a package with a unique name.
14.3.3.3. Constants: Another Class Variable Example
Lets try a less forced example of why you might want to use a class variable with the Circle class. When computing the area and circumference of circles, we use the value [pi]. Since we use the value frequently, we dont want to keep typing out 3.14159, so well define it as a class variable that has a convenient name:
public class Circle { public static final double PI = 3.14159265358979323846; public double x, y, r; // ... etc.... }
Besides the static keyword that weve already seen, we use the final keyword, which means that this variable can never have its value changed. This prevents you from doing something stupid like:
Circle.PI = 4;
which would tend to give you some pretty square-looking circles.
The Java compiler is smart about variables declared both static and finalit knows that they have constant values. When you write code like this:
double circumference = 2 * Circle.PI * radius;
the compiler precomputes the value 2 * Circle.PI, instead of leaving it for the interpreter.
Java does not have a preprocessor with a C-style #define directive. static final variables are Javas substitute for Cs #defined constants. Note that the C convention of capitalizing constants has been carried over into Java.
Lets define a new method in our Circle class. This one tests whether a specified point falls within the defined circle:
public class Circle { double x, y, r; // is point (a,b) inside this circle? public boolean isInside(double a, double b) { double dx = a - x; double dy = b - y; double distance = Math.sqrt(dx*dx + dy*dy); if (distance < r) return true; else return false; } . . // Constructor and other methods omitted . }
Whats this Math.sqrt() thing? It looks like a method call and, given its name and its context, we can guess that it is computing a square root. But the method calls weve discussed are done through an object. Math isnt the name of an object that weve declared, and there arent any global objects in Java, so this must be a kind of method call that we havent seen before.
14.3.4.1. static Methods
Whats going on here is that Math is the name of a class. sqrt() is the name of a class method (or static method) defined in Math. It differs from the instance methods, such as area() in Circle, that weve seen so far.
Class methods are like class variables in a number of ways:
14.3.4.2. No this
Class methods differ from instance methods in one important way: They are not passed as an implicit this reference. Thus, these this-less methods are not associated with any instance of the class and may not refer to any instance variables or invoke instance methods.
Since class methods are not passed a this reference, and are not invoked through an object, they are the closest thing that Java offers to the normal C procedures that you may be accustomed to, and may therefore seem familiar and comforting. If youre sick and tired of this object-oriented business, it is perfectly possible to write complete Java programs using only class methods, although this does defeat an important purpose of using the language!
But dont think that class methods are somehow cheatingthere are perfectly good reasons to declare a method static. And indeed, there are classes like Math that declare all their methods (and variables) static. Since Math is a collection of functions that operate on floating-point numbers, which are a primitive type, there are no objects involved, and no need for instance methods. System is another class that defines only class metodsit provides a varied collection of system functions for which there is no appropriate object framework.
14.3.4.3. A Class Method for Circles
Example 14.11 shows two (overloaded) definitions of a method for our Circle class. One is an instance method and one is a class method.
EXAMPLE 14.11. A class method and an instance method.
public class Circle { public double x, y, r; // An instance method. Returns the bigger of two circles. public Circle bigger(Circle c) { if (c.r > r) return c; else return this; } // A class method. Returns the bigger of two circles public static Circle bigger(Circle a, Circle b) { if (a.r > b.r) return a; else return b; } . . // Other methods omitted here. . }
You would invoke the instance method like this:
Circle a = new Circle(2.0); Circle b = new Circle(3.0); Circle c = a.bigger(b); // or, b.bigger(a);
And you would invoke the class method like this:
Circle a = new Circle(2.0); Circle b = new Circle(3.0); Circle c = Circle.bigger(a,b);
Neither of these is the correct way to implement this method. One or the other will seem more natural, depending on circumstances.
Previous | Table of Contents | Next |