13 Chapter Review Drill Answers and Explanations

AP Computer Science A Prep, 2024 - Rob Franek 2023

13 Chapter Review Drill Answers and Explanations
Part V: Content Review for the AP Computer Science A Exam

CHAPTER 3

1.E

Start by examining line 3 in the code segment: double c = a + b. Note that a is an integer variable and b is a double variable. When a double variable is added to an integer variable, the integer is automatically cast to a double before the addition takes place. Therefore, a + b will be 20.7; this value will be assigned to c.

Now look at line 4: int d = a + c. Because c is a double, a will once again be cast to a double and a + c will be 30.7. This value, which is a double, is then assigned to an integer variable. Because there is a loss of precision when a double value is assigned to an integer variable, the compiler will alert you. The correct answer is (E).

2.E

The key to this question is remembering that the cast operator (int) has precedence over the addition operator. First take a look at I. In that case, a will first be cast to an int (which has no effect because it is already an int) and then it will be added to b, which is still a double: the result of the addition will be a double, so you haven’t fixed the problem. You can therefore eliminate (A) and (D).

In II, a + b is enclosed in parentheses, so the addition will take place first. Adding a and b results in a double (20.7). This double is then cast to an int (20) and assigned to d. This is a legal assignment, so keep (B) and (E) and eliminate (C).

Now, look at III. Here, the double b (10.7) is first cast to an int (10). This int is added to a, which is also an int. When two ints are added, the result is also an int, so this expression is also valid. The correct answer is (E).

3.D

In line 5 of the code segment, divide a by b. Because both of the operands are integers, the result will be truncated to an int: 11 divided by 4 is 2.75, which is then truncated to 2. Now you know that the first number printed will be 2 (assuming you don’t run into a compilation error later in the code), so get rid of (A) and (B).

In line 7, once again divide 11 by 4. This time, however, the variables that hold these values are doubles. Therefore, the result of dividing 11 by 4 will also be a double: 2.75. Get rid of (C).

In line 9, yet again divide 11 by 4. The variable that holds 11 is an integer, while the variable that holds 4 is a double. With arithmetic operators, if one of the operands is a double and the other an integer, the integer is automatically cast to a double and the result of the operation is a double. Therefore, you get 2.75 again. The correct answer is (D).

4.E

In this question, you need to find the answer choice that doesn’t work. If the answer to this question is not obvious to you, the best approach is to try each answer choice and see whether it could be the value of i. If it can, then get rid of it.

Start with (A). Could i be equal to 0? Because x % 50 gives the remainder when x is divided by 50, for i to equal 0, x would have to be evenly divisible by 50. There are plenty of integers that would work for x (50, 100, 150…). In fact, any multiple of 50 would work.

How about (B)? Is there a positive integer we can pick for x that leaves a remainder of 10 when divided by 50? Well, because 50 is evenly divisible by 50, 50 + 10, or 60, would leave a remainder of 10 when divided by 50. Other numbers that would work include 110 and 160. In fact, if you add 10 to any positive multiple of 50, you will get a number that leaves a remainder of 10 when divided by 50.

Following the same logic, find numbers that leave remainders of 25 and 40 when divided by 50. For example, 75 and 90 would work. Therefore, get rid of (C) and (D).

The only choice left is (E). So why is it that you can’t get a remainder of 50 if you divide a positive integer by 50? Consider what happens if you divide 98 by 50. You get a remainder of 48. What if you divide 99 by 50? Now the remainder is 49. It seems if you increase 99 to 100, the remainder will increase to 50! But wait—100 divided by 50 actually leaves a remainder of 0.

The upshot of this example is that the value returned by the modulus operator will always be less than the operand to the right of the modulus operator. The correct answer is (E).

CHAPTER 4

1.E

Choices (A), (B), and (D) all have valid indices within s1. Choice (C) has valid indices: it will simply produce an empty string. Choice (E) will attempt to go out of bounds of the String because the last valid index is 4. The last possible index for the ending argument is 5 (substring would go up to that index, but not include the letter at that index).

2.C

Indices of characters within a string start at 0; thus the “a” is located at index 1. The second argument in the substring command is the ending index. The substring will go up to, but not include, this index. In this case, the substring will have a length of 1.

3.B

The command s1.length() returns 5, so String s4 = s1.substring(s1.length() - 2) will store the characters from s1, starting at index 3, to the end of the string. So (B) is the correct answer.

4.D

Using the return values of the compareTo method regarding lexicographical order:

(A) “january” precedes “July” (incorrect, uppercase comes first)

(B) “July” follows “June” (incorrect, “July” comes first)

(C) “january” precedes “June” (incorrect, uppercase comes first)

(D) “january” follows “June” (correct)

(E) “June” precedes “July” (incorrect, “July” comes first)

5.B

Line 2 finds the string “oo” at index 1, storing the 1 in variable p. Line 3 is a valid substring command, but it does not store the substring. Line 4 simply repeats what was done at line 2, finding the string “oo” at index 1 once again.

CHAPTER 5

1.C

You may have seen a problem like this one before. Be careful not to make assumptions; instead, note that i starts at 200 and is divided by 3 after each pass through the for loop. Note that i /= 3 is equivalent to i = i / 3, and integer division truncates the results. As you iterate through the loop, the values of i will be: 200, 66, 22, 7, 2.

In the body of the loop, i is printed if i % 2 equals 0. i % 2 gives the remainder when i is divided by 2; i will give a remainder of 0 when divided by 2 whenever i is even. Therefore, 200, 66, 22, and 2 will be printed; 7 will not be printed. The correct answer is (C).

2.A

Upon examination of both sides of the compound condition, p is combined with !q or q. If q is false, the left side (p && !q) has a chance of being true if p is also true. If q is true, the left side (p && q) has a chance of being true if p is also true. Thus, if p is true, we know for sure that either the left side OR the right side will be true. If p is false, both sides would be false. Thus, the overall expression will evaluate to the same value as p.

CHAPTER 6

1.A

This question tests your ability to reason through a nested loop. The first thing you should note is that the output is triangular. The first row has two elements, the second has three elements, and so on. Generally, the output of a nested loop will be triangular if the conditional statement of the inner loop is dependent upon the value of the outer loop. If the two loops are independent, the output is usually rectangular.

Trace through each answer choice and see which one will give you the first row: 0 1.

The first time you go through the inner loop in (A), x will be 1; because z starts at 0 and the loop continues while z is less than or equal to 1, the inner loop will print out 0 1. So keep this choice. For (B), the condition of the inner loop is that z is strictly less than x, so this will only print out 0. Get rid of (B). Choice (C) will print out 0 1 2 3 4, so get rid of that too. Choice (D) will print 0 2 4 for the first line. Get rid of it. Choice (E) prints 0 1 for the first line, so keep it for now.

You are now down to (A) and (E). Rather than tracing through each segment in its entirety, see what the differences are between each segment.

The only difference is the outer for loop. In (A), it is

for (int x = 1; x < 5; x++)

And in (E), it is

for (int x = 1; x <= 5; x++) (note the extra equals sign)

In (E), because the body of the outer loop is evaluated five times, it will print out five rows of numbers. Because the answer we are looking for prints only 4 rows, the correct answer must be (A).

2.A

Option I works correctly, so get rid of (B) and (C).

Option II is incorrect, because the conditional 65 <= speed < 75 is illegal. A variable can’t be compared to two numbers at once. This code will therefore cause a compile-time error. Get rid of (D).

Option III will compile and run, but it contains a logical error. Assume, for example, that a driver’s speed is 85 mph. The driver should receive a fine of $300. If you trace through the code, you see that the value of the variable fine is, in fact, set to $300 in the body of the first if loop because the driver’s speed is greater than or equal to 75. The problem is that the condition in the second if loop is also true: the driver’s speed is greater than 65. The body of the second loop is executed and the fine is set to $150. Finally, the condition in the third loop is also true, so the fine is then set to $100. Because III is incorrect, get rid of (E). (Note that III would have been correct if the programmer had put else in front of the second and third loops.) The correct answer is (A).

3.C

This question tests your ability to trace through a convoluted piece of code. A few things to note:

The body of the if loop is executed only if b is false.

The variable i is incremented by 5, not by 1, in the for loop.

The variable i is also incremented by 5 in the body of the if loop. This is something you would not normally do in your own code, but it is something you may see on the exam. Don’t assume the variable in the conditional of the for loop is modified only in the for loop.

4.B

Keep in mind that && returns true if both operands are true, || returns true if one or more of its operands are true, and ! reverses a boolean value.

The best way to crack questions involving booleans is often to just assign true or false to the variables and evaluate the expression.

Break (a && b) || !(a || b) into two pieces: (a && b) and !(a || b). The variable c will be assigned true if either of these pieces is true. (a && b) is true when both a and b are true. Therefore, get rid of (A) and (D).

See what happens if both a and b are false. Clearly (a && b) evaluates to false in this case, but what about !(a || b)? (a || b) is false if both a and b are false, but the ! operator inverts the value to true. So because !(a || b) is true, (a && b) || !(a || b) evaluates to true. Therefore, c will be assigned true when both a and b are false, so get rid of (C).

You are left with (B) and (E). See what happens when a is false and b is true. (a && b) evaluates to false. (a || b) is true, so !(a || b) is false. Therefore, (a && b) || !(a || b) is false and you can get rid of (E). The correct answer is (B).

5.E

The code will finish executing when the conditional in the while loop is false. In other words, when !(x > y || y >= z) is true. So figure out which of the answer choices is equivalent to !(x > y || y >= z).

Here’s how to solve it step by step:

Recall that !(a || b) is equivalent to !a && !b. So !(x > y || y >= z) becomes !(x > y) && !(y >= z).

!(x > y) is equivalent to x <= y, so you now have x <= y && !(y >= z).

!(y >= z) is equivalent to y < z, so you have x <= y && y < z. The correct answer is (E).

6.D

Each time the incremental statement a++ is evaluated, the value of a is increased by one. So to answer this question, you need to figure out how many times a is incremented.

The outer loop will be evaluated 10 times. The inner loop will be evaluated six times for each time that the outer loop is evaluated. The code in the body of the inner loop will therefore execute 6 × 10 or 60 times. Note that the condition k <= 5 evaluates to true when k equals 5. In the third loop, the value of z starts at 1 and is doubled after each pass through the loop. So the body of the innermost loop will execute when i equals 1, 2, 4, 8, and 16—or five times for each time the middle loop executes. Because 60 × 5 is 300, a will be incremented 300 times. The correct answer is (D).

7.D

The trick to this question is that arithmetic operators don’t modify their operands. So if x is 10 when we divide x by 3, the result is 3 but x remains the same. Likewise, taking the modulus of a number does not change the number itself. On the other hand, the post-increment operator (++) does change the value of the variable it operates on, so x++ will increase the value of x by 1. The correct answer is (D).

8.E

On the fourth line, a + b will be 13.7, but this result is cast to an int, so x will be 13. On the next line, a is first cast to a double and then divided by c. Because a is a double, c is automatically promoted to a double and the result of dividing the two is also a double. Therefore, y is 2.5.

On the next line, the parentheses cause the division to take place before the cast. Because a and c are ints, the result of dividing the two is truncated to an int, 2 in this case. The fact that we then cast the result to a double does not bring back the truncated decimal. Thus z is equal to 2, so w = 13 + 2.5 + 2. The correct answer is (E).

9.D

This question tests your understanding of short-circuit evaluation. In each code segment, pay attention to the conditional in the if statement.

In I, the conditional statement is x < y && 10 < y/z. First, x < y is evaluated. Because x is 10 and y is 20, x < y evaluates to true. Then check 10 < y/z. Because you divide by zero here, a run-time exception occurs. You can eliminate (A) and (E).

Now look at II. The conditional statement is x > y && 10 < y/z. Once again, first evaluate the operand to the left of the && operator. Because x is not greater than y, x > y evaluates to false. There’s no need to evaluate the right-hand operand. With the && operator, if the left operand is false, the whole condition is false. Because the right-hand operand is not evaluated, y is never divided by z and a run-time exception does not occur. This means (B) and (D) are still possible: eliminate (C).

In III, the conditional statement is x < y || 10 < y/z. The left-hand side, x < y, evaluates to true. Notice that this time you have the or operator || in the middle of the conditional. With an “or” statement, if the left-hand side is true, the condition is true regardless of the value of the right side. Because the left side is true, there is no need to evaluate the right-hand side, and the division by 0 error never occurs. The correct answer is (D).

CHAPTER 7

1.E

Because the database code can, in fact, be developed separately, tested separately, and possibly reused, all of the statements are correct. With questions like these, the easiest approach is to consider each candidate statement suspect, and look for ways in which they could be incorrect. If you find an incorrect one, cross off any answer choice that refers to it, including any choice that includes it AND another statement, because a combination of a true statement and a false statement is a false statement. Alternatively, when a candidate statement is true, put a star next to each answer choice that contains it. When you finish checking the statements, the one with the most stars wins.

In the above, because all three statements are true, we can cross off (A), (B), and (C) because each choice indicates that only one statement is correct. Similarly, cross off (D), because it dismisses the third statement. The correct answer is (E).

2.D

While the Java language makes it possible to make data fields public, one of the golden rules on the AP Computer Science A Exam is that data fields should always be designated private. Note that constants that are declared as static and final can be public; however, static constants apply to the class as a whole (because of the keyword static) and, thus, aren’t data fields.

Because data fields must be private, get rid of any answer choice that states they can be public. So get rid of (A), (B), and (E).

Now look at (C). What would happen if all methods in a class were private? Instances of the class would be useless because clients couldn’t ask the class to do anything for them. Classes need public methods to be useful. Eliminate (C).

What about (D)? The first part is good because data fields should be private. What about the second sentence? Above, you saw that methods can be public. They can also be private. A private method is used internally by a class to help out a public method, but is not directly accessible by client programs. The correct answer is (D).

3.C

Segment I is incorrect because it violates encapsulation. Thus, any answer that includes I can be dismissed out of hand. Thus, dismiss (A), (D), and (E). The implementation of a method can be changed without changing its client programs, so III is correct. Therefore, eliminate (B), which does not include III. Thus, the answer must be (C).

4.D

Both writeMe methods completely ignore the input that’s passed into them, so there’s no opportunity for “hi” to be printed. So (B) cannot be the answer. The code is syntactically correct, so (A) cannot be the answer. Along the same lines, you’re not doing anything that requires casting, or dealing with null, or dividing by a number that could potentially be 0, so (E) is not the answer. That leaves (C) and (D). Because you’re creating a String object and passing to a method that takes a string as a parameter, the existence of the writeMe(Object obj) method is inconsequential. Thus, the only valid answer is (D).

5.C

Both writeMe methods completely ignore the input that’s passed into them, so there’s no opportunity for “tmp” to be printed. So (D) cannot be the answer. The code is syntactically correct, so (A) cannot be the answer. Along the same lines, you’re not doing anything that requires casting, or dealing with null, or dividing by a number that could potentially be 0, so (E) is not the answer. That leaves (B) and (C). Because you’re creating an Object and passing to a method that takes an Object as a parameter, the existence of the writeMe(String s) method is inconsequential. Thus, the only valid answer is (C).

6.C

Both writeMe methods completely ignore the input that’s passed into them, so there’s no opportunity for “hi” to be printed. So (B) cannot be the answer. Use an Object reference to refer to a String instance, because a string IS-A Object. Thus, the code is not syntactically incorrect, so (A) is not the answer. That leaves (C), (D), and (E). Because you’re not doing any sort of casting, (E) is also an unlikely candidate. That leaves (C) and (D). Now the question becomes, when making overloaded calls, does Java pay attention to the type of the reference (which in this case is Object) or the type of the variable (which in this case is String)? It turns out that Java always pays attention to the type of the object, so (C) is correct.

7.A

tmp is an Object, not a String; thus the code snippet String tmp = new Object is illegal. This code will generate a compile-time error. The correct answer is (A).

8.B

This class is not declaring any methods at all, so (C) cannot possibly be correct. The code does not have any syntactical errors, so (A) cannot be correct. Choice (D) is nonsense because nothing can be both an attribute and a method, and (E), while true, is irrelevant. Being a primitive does not imply that val cannot be an attribute, so the “neither” part of the answer choice is a red herring. The correct answer is (B).

9.A

Both writeMe methods have the same name and same parameter list, but they return different types. This is illegal. Thus, (A) is the correct answer.

CHAPTER 8

1.B

The length of the word is 4, so [word.length() — 1] will allow for 3 elements.

2.C

On line 1, an array of String is created and assigned to reference s. Note that the array to which s refers can hold only two strings. This does not prevent you, however, from pointing s to another array that is not of length 2. This is exactly what happens on line 3; s is reassigned to the same array that t references. This array has a length of 3. The correct answer is (C).

Here is what this looks like:

Image

3.D

In the code segment, the variable a1 is declared as final. This means that once you assign an array to it, a1 must always point to that array. A compile-time error will occur when you try to assign the array referenced by b1 to a1. The correct answer is (D).

4.C

In the code segment, an array containing two integers is constructed and assigned to a variable named myArray. Because this reference is final, it cannot be assigned to another array. This does not prevent you, however, from changing the contents of the array that the variable myArray points to, as you do in the second line. The key here is that even though you change the contents of the array, it is still the same array. The correct answer is (C).

5.B

In the for loop in the method mod3, the variable i keeps track of the position in the array that you are inspecting for each iteration of the loop. numbers[i], on the other hand, is the value that is located at position i in the array. Option I will check to see whether position i is divisible by 3; that is not what you are looking for, so (A) and (D) are incorrect. Option II will check whether the number that is stored in the array at position i is divisible by 3, which is what you are looking for. Segment III will go into an infinite loop the first time it encounters an element in the array that is divisible by 3, so (C) and (E) can be eliminated. Only II will get the program to work as intended. The correct answer is (B).

6.C

Choice (A) does not assign the current values in arr to any element. Choice (B) will assign the contents of arr[3] to arr[0], thereby wiping out the original contents of arr[3].

The next three choices can be examined using trace tables. For each answer choice, let’s assume arr[0] = 4 and arr[3] = 5.

(C)


k

arr[0]

arr[3]


4

5

int k = arr[3];

5

4

5

arr[3] = arr[0];

5

4

4

arr[0] = k;

5

5

4

(D)


k

arr[0]

arr[3]


4

5

int k = arr[3];

5

4

5

arr[0] = arr[3];

Note: at this point we have lost the original value of arr[0]

5

5

5

arr[3] = k;

5

5

5

(E)


k

arr[0]

arr[3]


4

5

int k = arr[0];

4

4

5

arr[3] = arr[0];

4

4

4

arr[0] = k;

This swap has lost the original value of arr[0]

4

4

4

7. A

When using an enhanced-for loop with an array, each element is read into a local variable, in this case, s. While s may change within the loop, that change does not get implemented within the original array. Thus the elements in the array remain unchanged. Choice (A) is the correct answer.

8.D

This code is meant to reverse the order of the array by flipping the first element with the last, moving in toward the center.

The instruction middle = names.length/2 - 1; assigns a 2 to middle.

The for loop is controlled by x < middle so the two middle elements will not be flipped, because they are never accessed in the loop.

CHAPTER 9

1.C

Walk through this step by step. Remember that the add() method that takes just one argument adds the argument to the end of the list. The second and third lines of code add “A” and “B” to the ArrayList one after another:

list.add(“A”)

list.add(“B”)

After the code above executes, the list looks like

[A, B]

The next statement, list.add(0, “C”), adds “C” to the beginning of the list. Now the list looks like

[C, A, B]

After list.add(“D”) executes, the list looks like

[C, A, B, D]

The set() method replaces the value at the position indicated by the first argument. After list.set(2, “E”) executes, the list looks like

[C, A, E, D]

After list.remove(1) executes, the list looks like

[C, E, D]

The correct answer is, therefore, (C).

2.C

The key to this question is that as elements are removed from an ArrayList, the elements to the right of the removed element are shifted to the left, and their indices are reduced by 1.

On the first pass through the while loop, i will be 0. Because the string in position 0 of letters equals A, it is removed and letters looks like:

[B, A, A, C, D, B]

The next time through the while loop, i will be 1. The letter in position 1 is equal to A, so it is removed. Now letters looks like:

[B, A, C, D, B]

On the next pass through the ArrayList, i is 2. The letter in position 2 is a C, so it is not removed. The while loop will continue to iterate through the ArrayList, but because none of the strings in indices higher than 2 are equal to A, nothing else will be removed.

The correct answer is, therefore, (C).

3.D

The first time through the for loop, the letter in position 0 is removed and myList looks like:

[B, C, D, E]

The letter that is in position 0, which is now B, is printed.

The next time through the for loop, i is 1, so C, the letter in position 1, is removed. Now myList looks like:

[B, D, E]

The letter that is in position 1, which is now D, is printed.

At this point, i is incremented to 2. The size of myList is also 2, so i is no longer less than myList.size(). The for loop does not execute again.

The correct answer is, therefore, (D).

4.A

The first for loop initializes the ArrayList list so that it looks like

[1, 2, 3, 4, 5, 6, 7, 8]

Now take a look at the second for loop. Note that the highest value that j will reach is 7, one less than the size of the list. In the body of the for loop, the index of the position that you are setting is j divided by 2; the index can, therefore, never be greater than 3. In other words, you won’t be modifying any values other than those in the first 4 positions of the ArrayList. Knowing this, eliminate (D) and (E).

On the first pass through the loop, j is 1 and we call list.set(1 / 2, list.get(1)). Because the result of integer division is truncated, this call is equivalent to list.set(0, list.get(1)), so the value of the element at position 0 is the same as that of position 1 and the ArrayList is

[2, 2, 3, 4, 5, 6, 7, 8]

On the next pass through the for loop, j is 2 and we call list.set(1, list.get(2)). The ArrayList looks like this:

[2, 3, 3, 4, 5, 6, 7, 8]

On the next pass we call, list.get(1, list.get(3)). The ArrayList now looks like this:

[2, 4, 3, 4, 5, 6, 7, 8]

If you continue to iterate through the second for loop, the ArrayList will end up looking like this:

[2, 4, 6, 8, 5, 6, 7, 8]

The correct answer is (A).

CHAPTER 10

1.C

The variable identifier arr has already been created, eliminating (A), (B), and (E). While indices of arrays start at 0 and range to one less than the number of rows (or columns), the declaration should use the exact number of rows and columns desired in the array.

2.A

This is an enhanced-for loop. The first loop uses the concept that a two-dimensional array is an array of arrays. It pulls off one row at a time and stores it in nums. The inner loop takes one element at a time from the row and stores it in n. There are no line breaks, so the array is simply printed one element after another. This answer is (A).

3.D

The variable numbers.length is the number of rows in the two-dimensional array numbers. The variable numbers[0].length is the number of columns. Both the number of rows and the number of columns are 4.

On the first pass through the for loop, z is 0, and numbers[0].length ‒ 1 ‒ z is 3. So the value of numbers[0][3] is added to the total. numbers[0][3] is 3.

On the next pass, z is 1, numbers[0].length ‒ 1 ‒ z is 2, so the value of numbers[1][2] (which is 4) is added to the total.

On the next pass, add the value at numbers[2][1], which is 3, and on the final pass add the value at numbers[3][0], which is 4.

As you can see, the for loop simply finds the sum of one of the diagonals of the array. The correct answer is (D).

4.C

Note that k is incremented by 2 in the inner for loop. The code segment will find the sum of all the integers in columns with even indices.

numbers[0][0] + numbers[0][2] + numbers[0][4] + numbers[1][0] + numbers[1][2] + numbers[1][4] + numbers[2][0] + numbers[2][2] + numbers[2][4] = 37

5.A

For each cell in the two-dimensional array, the code sets the value to the product of the indices for that cell. For example, num[2][3] is set to 2 × 3 or 6. The correct answer is (A).

6.E

The index a will range from 0 to 3, while index b will range from 0 to 1. The indices are used in [b][a] order. The table below will help to visualize the traversal of the array. Each time b reaches the maximum index of rows, it will add a line break. The answer is (E).

b

a

s

0

0

1

1

0

1 5 “\n”

0

1

1 5 “\n” 2

1

1

1 5 “\n” 2 6 “\n”

0

2

1 5 “\n” 2 6 “\n” 3

1

2

1 5 “\n” 2 6 “\n” 3 4 “\n”

0

3

1 5 “\n” 2 6 “\n” 3 4 “\n” 4

1

3

1 5 “\n” 2 6 “\n” 3 4 “\n” 4 8

7. E

The array m is declared using the number of rows (arr.length). Thus, there must be 3 entries, eliminating A and C. Index i will refer to each row. The number 2 is passed to n; thus, the column at index 2 (column 3) will be accessed. The correct column is 3 7 11.

8.D

The index r starts traversing the array on the last row. The program accesses each element in the row and assigns it to the row above it. This has the net result of changing all the elements to be the same values as those in the last row.

CHAPTER 11

1.E

If a constructor does not exist for a subclass, a default constructor with no parameters is generated in the superclass. This allows choices (A) and (B) to construct a Parent object and a Child object, respectively. Choice (C) will work: it will simply print null because the instance field str was never initialized. Choice (D) will invoke the inherited write() method from the Parent class, printing null once again. Choice (E) will cause an error because there is no method named write() that is expecting an int parameter in either class. The correct choice is (E).

2.B

A class can, at most, directly extend one other class.

3.E

Since Manager extends Employee, a manager is an Employee. Choices (A) and (B) will create Employee objects using two different Employee objects. Choices (C) and (D) create Manager objects with a more generic type (Employee). This is perfectly allowable, but not the other way around. Thus, (E) is invalid because it is trying to create an Employee object with a more specific type.

4.D

If a parent class constructor is not called explicitly, the default constructor will be called. Thus, when the Croissant() constructor is called, before any lines of code within the constructor are executed, it calls the default constructor of the Pastry class. Before any lines of code are executed within the default Pastry constructor, the default Bread constructor is called. It is within this constructor that “Freshly baked bread smells good” will be printed. Execution returns to the Pastry constructor where “Baking pastry is an art” is printed. Control finally returns to the Croissant constructor where “Croissants taste buttery” is printed. The correct answer is (D).

5.A

Subclasses inherit fields and methods from the superclass. Even though there is no toString method in the Croissant class, the toString method in the Bread class will be invoked and bread will be printed. The answer is (A).

6.C

This is a good question on which to use Process of Elimination. Don’t try to find the best design right away. Instead, first get rid of the answer choices that you know are flawed.

The use of the word unrelated is a tip-off that (A) is incorrect. In general, classes and data fields in a program will be related to each other; otherwise, there would really be no point in writing the program in the first place.

Now look at (B). Whenever you are trying to decide whether one class is a subclass of the other, ask yourself whether an instance of the proposed subclass IS-A instance of the proposed superclass. For example, in this case you could ask whether a Pet IS-A Apartment. Obviously not, so get rid of (B).

Choice (C) looks good. Using primitive data fields allows you to store information about the Apartment within an instance of the class. Check the rest of the answer choices, though.

Like (B), (D) refers to subclasses. The difference this time is that Apartment is a subclass of the other classes. There are two problems here. First of all, the IS-A relationship doesn’t hold. It would be incorrect to say that an Apartment IS-A Pet, Room, or Dishwasher. Here’s the other problem: if Apartment is a subclass of all three of the other classes, then that means that Apartment has three immediate superclasses; in other words, Apartment extends three of the classes. However, in Java, a class can extend only one other class.

Finally, (E) uses a HAS-A relationship (this is also called composition). This design is similar to that of (C), except it uses objects instead of primitives, which (C) used. In this case, using objects will be overkill. For example, the specification from the rental company states only that they want to know whether the apartment has a dishwasher. A boolean can be used to store this information, so there’s really no point in building a Dishwasher class. On the other hand, if the rental company had specified that they needed to store a lot of information about the type of dishwasher in each apartment, such as its color, manufacturer, and year of installation, then a Dishwasher class would be appropriate.

The correct answer is, therefore, (C).

7.D

Choice (A) is incorrect because the Motorcycle class does not define a constructor that takes one argument. Note that unlike other methods, constructors are not inherited, so even though Motorcycle extends Vehicle, and Vehicle defines a constructor that takes one argument, Motorcycles will not inherit this constructor.

Choice (B) is incorrect for the same reason that (A) is incorrect. Even though the reference type is Vehicle, you are still constructing a Motorcycle, and the Motorcycle class does not define a constructor that takes one argument.

In (C), you are creating a Vehicle and assigning it to a reference of type Motorcycle. This is incorrect because a Vehicle is not necessarily a Motorcycle. The reference type of a variable must be the same class or a superclass of the object that you are trying to assign to it. It cannot be a subclass.

Choice (D) is correct. Because the Motorcycle class extends the Vehicle class, a Motorcycle IS-A Vehicle and we can assign a Motorcycle instance to a Vehicle reference.

The first line in (E) is correct. However, in the second line, you are trying to access a private data member. To fix this, you would need to call the public method maxPassengers() instead. This would look like the following:

int max = v3.maxPassengers();

Always bear in mind that all data members on the exam will be private; only methods are public. Therefore, when you use dot notation on an instance of a class, the part that follows the dot should end in parentheses. The only exception to this that you will see on the exam is the length attribute of an array.

CHAPTER 12

1.D

The recursion is as follows:

mystery(6) = 2 * mystery(5)

mystery(5) = 2 * mystery(4)

mystery(4) = 2 * mystery(3)

mystery(3) = 2 * mystery(2)

mystery(2) = 2 * mystery(1)

mystery(1) = 2;

So mystery(6) = 2 * 2 * 2 * 2 * 2 * 2 = 64.

The correct answer is (D).

2.D

On the first pass through the method, you get

10 + mystery(10 / 2) + mystery(10 / 4)

Which can be simplified to

10 + mystery(5) + mystery(2)

Now figure out what mystery(5) and mystery(2) are and add the results to 10.

First, solve mystery(5):

mystery(5) = 5 + mystery(5 / 2) + mystery(5 / 4) = 5 + mystery(2) + mystery(1)

mystery(2) = 2 + mystery(2 / 2) + mystery(2 / 4) = 2 + mystery(1) + mystery(0)

mystery(1) = 1 + mystery(1 / 2) + mystery(1 / 4) = 1 + mystery(0) + mystery(0)

Note that mystery(0) is our base case and returns 0. Working your way back up the recursive calls, you find that mystery(1) = 1, mystery(2) = 3, and mystery(5) = 9. Note that in solving mystery(5), you ended up needing to solve mystery(2).

So in the original equation, 10 + mystery(5) + mystery(2), you can replace mystery(5) with 9 and mystery(2) with 3 to get 10 + 9 + 3, which equals 22. The correct answer is (D).

3.A

For any non-negative number n that is passed as an argument to the non-recursive method mystery(), the method will return 0 + 1 + 2 + 3 +…+ n. For example, a call to mystery(5) will return 0 + 1 + 2 + 3 + 4 + 5 = 15. Note that the border case for mystery() occurs when 0 is passed to the method. In this case, the method returns 0.

I (method mystery2()) is equivalent to mystery().

II (mystery3()) is not equivalent. Notice that mystery3() does not modify what is returned by the recursive call, whereas mystery2() adds x to the results of each recursive call. The method mystery3() will return 0 regardless of the value that is passed to the method.

III (mystery4()) is equivalent to mystery() except when x equals 0. If 0 is passed to the method, the loop will infinitely recurse. Because mystery4() doesn’t handle the border case correctly, III is incorrect.

Only I is equivalent to the mystery() method, so (A) is correct.

4.B

You originally pass 30 and 18 to the method as x and y, respectively. Each time the method is recursively called, 10 is added to x and 3 is subtracted from y. Therefore, x will eventually become larger than 100 and y will become smaller than 0, so you know that the condition of the base case will eventually be met, and infinite recursion won’t occur. Eliminate (E).

Note that the base case returns 1. What about the non-base case? The method return mystery (x + 10, y ‒ 3) simply returns whatever was returned by the call to mystery(); it doesn’t modify it in any way. Because there’s no modification of the return value, 1 is the only thing that is ever returned, no matter how many recursive calls occur. The correct answer is (B).

5.B

The best way to solve this problem is to trace through each answer choice. But don’t necessarily start with (A). Start with the answer choice that you think you can solve most quickly. In this case, (A) will probably take longer to check because it has two recursive calls. Instead, start with (D). Why (D)? Because each recursive call reduces the integer that you pass as an argument by 4, there won’t be as many recursive calls as there will be with the other choices.

With (D), the first time through the method, you have mystery(10) = 4 * mystery(6). Find that mystery(6) = 4 * mystery(2) and mystery(2) = 4 * mystery(‒2). Finally, mystery(‒2) equals 1 (the base case). Working your way back up the call stack, you get mystery(2) = 4, mystery(6) = 16 and mystery(10) = 64. So (D) is incorrect.

The choice with the next fewest recursive calls is (B). For this choice, mystery(10) = 2 * mystery(8); mystery(8) = 2 * mystery(6); mystery(6) = 2 * mystery(4); mystery(4) = 2 * mystery(2); mystery(2) = 2 * mystery(0); and mystery(0) = 1. Therefore, mystery(2) = 2; mystery(4) = 4; mystery(6) = 8; mystery(8) = 16; and mystery(10) = 32. The correct answer is (B).