CSCI 261 Fall 2021 -- Exam #1 Solutions Problem 1 --------- An interface contains method signatures (names, parameters, return types) but no code for any of their bodies. It's used as a way to get polymorphism across classes that implement the interface. For example, we could sort arrays full of any kinds of objects that implement the Comparable interface, or use our graphical controller on any classes implementing Controllable. An abstract class is one in which at least one method is abstract (missing its body), but it can contain other "normal" methods as well. It's useful when creating a "starter kit" for subclasses, like the AbstractList class that's extended to get ArrayList and other lists, or the DieParent class we discussed in class. Problem 2 --------- It's always safe to substitute an instance of a subclass for an instance of its parent class because subclasses contain all of the methods that their parent classes do -- they either inherit them from their parent, or override them with a new definition. Thus any methods we could call on an instance of the parent class are safe to call on instances of subclasses. Problem 3 --------- a) The loop is controlled by the size of the ArrayList that's passed in, so n is the length of the list. b) Once: new, =, =0, return Once per iteration: .size(), >0, .size(), nextInt(), =, .get(), =, .roll(), +, =, .remove() That gives T(n) = 11n + 4 if we just count .roll() as a single operation. We know it's at least four operations from our discussions in class, so I'll use T(n) = 14n + 4 c) Discarding lower-order terms and constants, we get: O(n) That's an appropriate simplification of T(n) since with c=15, our O(n) approximation is >= 14n + 4 for all n > an n0 of 4. (That is, c=15 and n0=4.) d) We need to make sure that any die throwing an exception gets removed from the list, otherwise we could get stuck repeatedly catching an exception from a broken die. We could do this: public static int rollDice(ArrayList dice) { Random rng = new Random(); int total = 0; while(dice.size() > 0) { int index = rng.nextInt(dice.size()); BasicDie d = dice.get(index); try { total = total + d.roll(); dice.remove(index); } catch(Exception e) { dice.remove(index); } } return total; } Or, we could just do the remove() outside the try/catch: public static int rollDice(ArrayList dice) { Random rng = new Random(); int total = 0; while(dice.size() > 0) { int index = rng.nextInt(dice.size()); BasicDie d = dice.get(index); try { total = total + d.roll(); } catch(Exception e) { // Nothing to do here } dice.remove(index); } return total; } Problem 4 --------- /** * The BetterRadio class works with the Controller from the most * recent assignment. Radio already had up() and down() methods, so * we can use the inherited versions of those. We just need to * define the other required methods from the interface, and then * call the appropriate methods in our parent class. */ public class BetterRadio extends Radio implements Controllable { /** function() just calls reset() in the parent class */ public void function() { super.reset(); } /** left() just calls down() in the parent class */ public void left() { super.down(); } /** right() just calls up() in the parent class */ public void right() { super.up(); } }