Page 309 - Introduction to Programming with Java: A Problem Solving Approach
P. 309
7.10 Problem Solving with Multiple Driven Classes 275
To avoid creating a separate object, Java designers came up with special syntax that allows an over- loaded constructor to call one of its partner overloaded constructors such that the original object is used. Here is the syntax:
this(<arguments-for-target-constructor>);
A this(<arguments-for-target-constructor>) constructor call may appear only in a constructor defini- tion, and it must appear as the very first statement in the constructor definition. That means you can’t use this syntax to call a constructor from inside a method definition. It also means you can have only one such constructor call in a constructor definition, because only one call statement could be the “very first state- ment in the constructor definition.”
Now look at the Fraction class in Figure 7.19. It has three instance variables—numerator, denominator, and quotient. The quotient instance variable holds the floating-point result of di- viding the numerator by the denominator. The first constructor is just like the two-parameter constructor we wrote above. But the second constructor is shorter. Instead of repeating code appearing in the first construc- tor, it calls the first constructor with the this(...) command.
Suppose during program development, for debugging purposes, you decided to print “In 1-parameter constructor” from within the Fraction class’s one-parameter constructor. Where would you put that print statement? Since the this(n, 1) constructor call must be the first statement in the constructor definition, you would have to put the print statement below the constructor call.
Tracing with Constructors
Figure 7.20 shows a trace of the Fraction program. In the following discussion of it, you’ll need to actively
Apago PDF Enhancer
refer to not only the trace figure, but also the FractionDriver class (Figure 7.18) and the Fraction class (Figure 7.19). Note how line 12 in the FractionDriver class passes 3 and 4 to the two-parameter Fraction constructor. 3 and 4 are assigned to the constructor’s n and d parameters. As part of the implied constructor functionality, lines 10-12 in the Fraction class are executed, and they initialize Fraction instance variables with their default values. Then lines 25-27 overwrite those initialized values. Going back to FractionDriver, new returns an object reference (obj1) to the reference variable a. Then on line 13, the driver passes 3 to the one-parameter constructor. After parameter assignment and instance vari- able initialization, line 18 in the Fraction class passes 3 and 1 to the two-parameter constructor. After the two-parameter constructor overwrites the instance variables, control flows back to the one-parameter constructor, and back to FractionDriver, where new returns an object reference (obj2) to the reference variable b. Finally, in lines 15 and 16, the driver prints out the two results.
7.10 Problem Solving with Multiple Driven Classes
We started simply and we are gradually adding complexity. In Chapters 1 through 5, we showed you pro- grams that contain only one class and one method (the main method). In Chapters 6 and 7 we’ve been showing you programs that contain two classes: (1) a driver class, which contains a single main method and (2) a driven class, which typically contains several methods.
So far we’ve used only one driven class to keep things simple, but in the real world, you’ll often need more than one driven class. That’s because most real-world systems are heterogeneous—they contain mix- tures of different types of things. For each different type of thing, it’s appropriate to have a different class. Having more than one driven class allows you to partition a complicated problem into several simpler prob- lems. That lets you focus on one type of thing at a time. When you’ve finished that type of thing, you can move onto another type of thing. In this step-by-step fashion you can gradually build up a large program.