}
But this code won't compile.
The problem is that the class attempting to access the protected member is PriorityQueue while the
type of the reference to the object being accessed is SingleLinkQueue. SingleLinkQueue is not the
same as, nor a subclass of, PriorityQueue, so the access is not allowed. Although each
PriorityQueue is a SingleLinkQueue, not every SingleLinkQueue is a PriorityQueue.
The reasoning behind the restriction is this: Each subclass inherits the contract of the superclass and expands
that contract in some way. Suppose that one subclass, as part of its expanded contract, places constraints on
the values of protected members of the superclass. If a different subclass could access the protected members
of objects of the first subclass then it could manipulate them in a way that would break the first subclass's
contractand this should not be permissible.
Protected static members can be accessed in any extended class. If head were a static field, any method
(static or not) in PriorityQueue could access it. This is allowed because a subclass can't modify the
contract of its static members because it can only hide them, not override themhence, there is no danger of
another class violating that contract.
Members declared protected are also available to any code within the package of the class. If these
different queue classes were in the same package, they could access one another's head and tail fields, as
could any unrelated type in that package. Classes in the same package are assumed to be fairly trustworthy
and not to violate each other's contractssee Chapter 18. In the list "private, package, protected, public," each
access level adds to the kinds of code to which a member is accessible.
3.6. Marking Methods and Classes final
Marking a method final means that no extended class can override the method to change its behavior. In
other words, this is the final version of that method. Entire classes can also be marked final:
final class NoExtending {
// ...
}
A class marked final cannot be extended by any other class, and all the methods of a final class are
themselves effectively final.
Final classes and methods can improve security. If a class is final, nobody can declare a class that extends
it, and therefore nobody can violate its contract. If a method is final, you can rely on its implementation
details (unless it invokes non-final methods, of course). You could use final, for example, on a
validatePassword method to ensure that it does what it is advertised to do instead of being overridden to
always return TRue. Or you can mark as final the class that contains the method so that it can never be
extended to confuse the implementation of validatePassword.
Marking a method or class final is a serious restriction on the use of the class. If you make a method
final, you should really intend that its behavior be completely fixed. You restrict the flexibility of your
class for other programmers who might want to use it as a base from which to add functionality to their code.
Marking an entire class final prevents anyone else from extending your class, limiting its usefulness to