CS 310, Object-Oriented Programming with Java

Quiz 6, 26 February 2009


  1. When implementing an interface in a class, what is the set of allowable access permissions that may be correctly assigned to the overridden interface methods? Justify your answer.


    Overridden interface methods may only have the public access permission assigned. The methods are assigned public assess in the interface, and an overridden method cannot be assigned a more restrictive access permission in the descendant class. Because public is the least restrictive access permission, it is the only acceptable access permission for overridden methods. Page 248.

    The answers, approximately verbatim, in no particular order, and with comments in italic:

    • Public. All abstract methods of an interface are public and it is not possible to override a method using more restrictive access permissions.

    • The set of allowable access permissions that are assigned to override interface methods are public access.1 Classes implementing an interface needs to be allowed to access the interface methods, so they must have public access.2

      1: This is a terrible sentence; it’s too long and convoluted. If you must err, err on the side of brevity.

      2: True, but a child’s ability to access a parent’s feature is determined by the access permission assigned in the parent. The question (perhaps implicitly) is asking about the access permission assigned in the child.

    • The allowable access permission is public because all methods within an interface is automatically set to public whether explicitly written or not. If the method is not set as public when being overridden, the class implementing the interface will become abstract3,4 because it will not have actually overwritten the method,5 resulting in an abstract method from the interface being within the class.6

      3: If the overridden interface method is not explicitly assigned an access permission, it will receive the package default permission.

      4: This seems to be confusing access permissions with the abstract keyword; these are separate, independent ideas.

      5: The problem states the method is overridden.

      6: True, but that only happens when the child fails to override an abstract method inherited from its parent or an implemented interface.

    • All methods signatures that are declared in an interface are public static,7 therefore when implementing an interface, overridden methods must be declared “public” or else they will receive package access resulting in a compiler error.

      7: All interface methods are public abstract; interface fields (they can’t be called variables because they don’t vary) are public final static. Although a static interface method might make some sense, it’s not legal syntax.

    • An interface’s method are public final by default.8 Within a class, you can reassign the access to be private to restrict other classes from outside the scope of the class implementing the interface.9

      8: A final interface method is contradictory. The final keyword indicates a method can’t be overridden in descendants, while an interface method must be overridden in descendants.

      9: That depends on whether the method is inherited or not. Inherited methods must be assigned access permissions no less restrictive than that assigned in the parent; this rule preserves protocol satisfaction. Non-inherited methods can be assigned any access permission.

    • To implement an interface in an class it10 must be public and extend the class. If it does not do this11 then it acts like an abstract class, and can only extend one class.12

      10: Which it: interface or class?

      11: Which this: be public or extend the class (or perhaps both)?

      12: A child can only ever extend exactly one class, independent of whether or not the child’s abstract.

  2. True or false: when overriding the Object.clone() method in class C, every ancestor of C, except for Object, has to override Object.clone() too. Justify your answer.


    True for at least to reasons, one straightforward, the other less so.

    The straightforward reason is a matter of good programming. Cloning a class instance involves making copies all fields in the class, including those in ancestors. Although a class could be required to be aware of every feature offered in all its ancestors1 to the extent of being able to make a copy of them, writing clone() under those conditions would be cumbersome at best. In addition, any change to an ancestor’s field set would require rewriting all the descendant clone()s.

    The more obscure reason relates to what clone does: it creates an instance without calling a class’s constructors. Regular, programmer defined classes don’t have this ability (apart from calling clone() and a few other tricks); making a clone requires magic. Because Object is already magical — it doesn’t have a parent, for example — it makes sense to put the cloning magic in Object.clone(). As a consequence, every descendant clone() must defer to Object.clone() to create the instance; that is, there must be an unbroken sequence of super.clone()s from the descendant to Object. Page 252.

    1: You might want to argue that a class couldn’t be required to know about all ancestor features because some of them might be private; that is, inaccessable to descendants. That’s true, but the requirement’s being offered up as a hypothesis, and the hypothesis could include the requirement that the descendant knows about private ancestor fields when cloning.

    The answers, approximately verbatim, in no particular order, and with comments in italic:

    • True. It is true that it1 must override because Object.clone does not act like a regular interface2 and it is default private so you need to make it public so it can make either a soft copy or a hard copy.3

      1: Which it? There are at least two: the class itself and the Object ancestor.

      2: Object.clone() is a method, not an interface. And the Cloneable interface is an odd-ball because it doesn’t define any methods.

      3: That should probably be “a shallow copy or a deep copy.”

    • False. Because clone() is in the Object class, and all classes are descendants of Object, all classes inherit a clone method.4 The problem is that the default clone method may not act the way that you want it to.5 If for some reason you call one of C’s ancestor’s clone, you will get Object’s clone, and it may not behave the way you want it to.6

      4: True, but the question’s asking if the inherited clone()s should be overridden.

      5: True, but that sounds like an argument for overriding.

      6: True, but that’s another argument for overriding.

    • This is false. The clone method in the Object class has protected access. To have class C call clone,7 class C must set the clone method to public and the implement the clone method. All other ancestors of Class C do not need to override the clone method because only C wants to call the method.8

      7: Which clone(): the one in Object or the one being overridden in C? Or maybe in one of C’s ancestors?

      8: What happens when one of C’s ancestors overrides Object.clone() independently of what C does?

    • False. When you override the Object.Clone() method for a descendant class of Object (in this case, C), you are changing Object.clone() method’s behavior for C and its possible descendant classes.9 The clone() method in the class C will be found first and used by the compiler.10 The compiler will not look further up the classes for the clone() method.11

      9: True, which is why each overridden clone() should start with super.clone().

      10: The run-time look-up does that; the compiler plants the code for the look-up.

      11: True, but should the clone() dynamic look-up stop at C’s clone() or should it continue up the ancestor chain? That’s the question.

    • True. The reason is any of C’s ancestors are able to hold a C instance.12 Therefore if Object.clone() is called when C’s ancestor is holding a C instance, an error will occur.13

      12: True, but the static (or declared) type of the variable holding C’s instance will be an ancestor of C’s ancestor; C has no idea what its descendants will be called.

      13: Object.clone() copies values from variable to variable. Java’s static typing insures the values are type correct with respect to the variables; what errors could occur?

    • True. An overridden clone method should begin with a call to super.clone(). Given the access permissions on Object.clone(), a class must override clone in order to use it.14

      14: Object.clone() has protected access permission; descendants have no problems accessing Object.clone(). The access problem occurs when a non-related class D wants to call C.clone(); D can access C.clone() only if D’s in the same package as C. If that’s too restrictive, C should override clone() with public access.


This page last modified on 2 March 2009.