Download Java: Understanding Points and Rectangles as Objects and more Assignments Computer Science in PDF only on Docsity! Chapter 8 Objects as containers 8.1 Points and Rectangles In this chapter, we are going to use two new object types that are part of the Java language, Point and Rectangle. Right from the start, I want to make it clear that these points and rectangles are not graphical objects that appear on the screen. They are variables that contain data, just like ints and doubles. Like other variables, they are used internally to perform computations. 8.2 Packages The built-in Java classes are divided into a number of packages, including java.lang, which the most commonly-used classes, and which is imported au- tomatically, and java.awt, which contains classes that pertain to the Java Ab- stract Window Toolkit (AWT). The AWT contains classes for windows, but- tons, graphics, etc. In order to use a package, you have to import it using (surprise) an import statment. All import statements appear at the beginning of the program, outside the class definition. To import a specific class from a package: import java.util.Stack; This imports the Stack class from the java.util package. More often, we want to import all the classes from a package, using the * operator: import java.awt.*; This imports all the classes in the AWT package. The definitions of the Point and Rectangle classes are in java.awt, so any program that uses them should include this import statement. The documentation for all Java packages is available online from 73 74 CHAPTER 8. OBJECTS AS CONTAINERS http://java.sun.com/products/jdk/1.1/docs/api/packages.html for Java version 1.1 and http://java.sun.com/products/jdk/1.2/docs/api/overview-summary.html for Java version 1.2. 8.3 Point objects A point is two numbers (coordinates) that we treat collectively as a single object. In mathematical notation, points are often written in parentheses, with a comma separating the coordinates. For example, (0, 0) indicates the origin, and (x, y) indicates the point x units to the right and y units up from the origin. In Java, a point is represented by a Point object. To create a new point, you have to use the new command: Point blank; blank = new Point (3, 4); The first line is a conventional variable declaration: blank has type Point. The second line invokes the new command to create the new point, (3, 4). The result of the new command is a reference to the new point, as shown here: blank 3x: y: 4 The big box shows the newly-created object with the instance variables for the Point class, x and y. 8.4 Instance variables You can access the instance variables of an object using “dot notation.” int x = blank.x; The expression blank.x means “go to the object blank refers to, and get the value of x.” In this case we assign that value to a local variable named x. Notice that there is no conflict between the local variable named x and the instance variable named x. The purpose of dot notation is to identify which variable you are referring to unambiguously. 8.9. ALIASING 77 x: y: 0 0 box 200 width: height:100 100 50 We could take this code and encapsulate it in a method, and generalize it to move the rectangle by any amount: public static void moveRect (Rectangle box, int dx, int dy) { box.x = box.x + dx; box.y = box.y + dy; } The variables dx and dy indicate how far to move the rectangle in each direction. Invoking this method has the effect of modifying the Rectangle that is passed as an argument. Rectangle box = new Rectangle (0, 0, 100, 200); moveRect (box, 50, 100); System.out.println (box); prints java.awt.Rectangle[x=50,y=100,width=100,height=200]. Modifying objects by passing them as arguments to methods can be useful, but it can also make debugging more difficult because it is not always clear which method invocations modify their arguments. Later, I will discuss some pros and cons of this programming style. In the meantime, we can enjoy the luxury of Java’s built-in methods, which include translate, which does exactly the same thing as moveRect, although the syntax for invoking it is a little different. It is an object method, so instead of passing the Rectangle as an argument, we invoke translate on the Rectangle and pass only dx and dy as arguments. box.translate (50, 100); The effect is the same. 8.9 Aliasing Remember that when you make an assignment to an object variable, you are assigning a reference to an object. It is possible to have multiple variables that refer to the same object. For example, this code: Rectangle box1 = new Rectangle (0, 0, 100, 200); Rectangle box2 = box1; 78 CHAPTER 8. OBJECTS AS CONTAINERS generates a state diagram that looks like this: x: y: width: 100 200 0 0 height: box1 box2 Both box1 and box2 refer or “point” to the same object. In other words, this object has two names, box1 and box2. This is an example of aliasing. When two variables are aliased, any changes that affect one variable also affect the other. For example: System.out.println (box2.width); box1.grow (50, 50); System.out.println (box2.width); The first line prints 100, which is the width of the Rectangle referred to by box2. The second line invokes the grow method on box1, which expands the Rectangle by 50 pixels in every direction (see the documentation for more details). The effect is shown in the figure: x: y: 0 0 box1 box2 100 200 width: height: -50 -50 200 300 As should be clear from this figure, whatever changes are made to box1 also apply to box2. Thus, the value printed by the third line is 200, the width of the expanded rectangle. (As an aside, it is perfectly legal for the coordinates of a Rectangle to be negative.) As you can tell even from this simple example, code that involves aliasing can get confusing fast, and it can be very difficult to debug. In general, aliasing should be avoided or used with care. 8.10 null When you create an object variable, remember that you are creating a reference to an object. Until you make the variable point to an object, the value of the variable is null. null is a special value in Java (and a Java keyword) that is used to mean “no object.” 8.11. GARBAGE COLLECTION 79 The declaration Point blank; is equivalent to this initialization Point blank = null; and is shown in the following state diagram: blank The value null is represented by a dot with no arrow. If you try to use a null object, either by accessing an instance variable or invoking a method, you will get a NullPointerException. The system will print an error message and terminate the program. Point blank = null; int x = blank.x; // NullPointerException blank.translate (50, 50); // NullPointerException On the other hand, it is legal to pass a null object as an argument or receive one as a return value. In fact, it is common to do so, for example to represent an empty set or indicate an error condition. 8.11 Garbage collection We have talked about what happens when more than one variable refers to the same object. What happens when no variable refers to an object? For example: Point blank = new Point (3, 4); blank = null; The first line creates a new Point object and makes blank refer to it. The second line changes blank so that instead of referring to the object, it refers to nothing (the null object). blank 3x: y: 4 If no one refers to an object, then no one can read or write any of its values, or invoke a method on it. In effect, it ceases to exist. We could keep the object in memory, but it would only waste space, so periodically as your program runs, the Java system looks for stranded objects and reclaims them, in a process called