THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

If the enclosing class of the inner subclass is not a subclass of Outer, or if the inner subclass is not itself an
inner class, then an explicit reference to an object of Outer must be supplied when the Inner constructor is
invoked via super. For example:


class Unrelated extends Outer.Inner {
Unrelated(Outer ref) {
ref.super();
}
}


When the construction of an Unrelated object reaches the point where the superclass constructor is
invoked, there must be an object of class Outer to which the superclass object can be bound. Since
Unrelated is not itself an inner class of Outer, there is no implicit enclosing object. Similarly, because
Unrelated is not a subclass of Outer, the current object of Unrelated is not a valid enclosing object.
We must provide an explicit reference to an Outer object for the superclass object to bind to. We chose to
supply that reference using an argument to the Unrelated constructor, which uses it as an explicit binding
reference in the invocation of the superclass constructor.


Note that you cannot use the inner class creation syntax to externally provide an Outer object, as in


Outer ref = new Outer();
Unrelated u = ref.new Unrelated(); // INVALID


because this syntax supplies an enclosing object for the Unrelated class and Unrelated is not an inner
class.


An inner class can extend another, unrelated, inner class provided an appropriate enclosing instance is
supplied to the superclass, as just described. The resulting inner class then has two enclosing instancesone for
the extended class and one for the superclass. Such designs are convoluted, however, and are best avoided.


5.2.3. Inheritance, Scoping, and Hiding


Within an inner class, all names declared within the enclosing class are said to be in scopethey can be used as
if the inner class code were declared in the outer class. An inner class's own fields and methods (and nested
types) can hide those of the enclosing object. There are two ways in which this can occur:



  • a field or method is declared in the inner class

  • a field or method is inherited by the inner class


In both cases any use of the simple name refers to the member of the inner class, whether declared or
inherited. The enclosing object's field or method must be accessed explicitly using a qualified-this
expression.


In the second case, the use of the simple name can mislead a reader of the code. Consider the following:


class Host {
int x;


class Helper extends Unknown {
void increment() { x++; } // Not what you think!
}
}

Free download pdf