// Example 1
public class InnerInnerTest {
public static void main(String s[]) {
new Outer().new Inner().new InnerInner().new InnerInnerInner().doSomething();
new Outer().new InnerChild().doSomething();
new Outer2().new Inner2().new InnerInner2().doSomething();
new InnerChild2().doSomething();
}
}
class Outer {
String name = "Vel";
class Inner {
String name = "Sharmi";
class InnerInner {
class InnerInnerInner {
public void doSomething() {
// No problem in accessing without full qualification,
// inner-most class variable shadows the outer-most class variable
System.out.println(name); // Prints "Sharmi"
System.out.println(Outer.this.name); // Prints "Vel", explicit reference to Outer
// error, variable is not inherited from the outer class, it can be just accessible
// System.out.println(this.name);
// System.out.println(InnerInner.this.name);
// System.out.println(InnerInnerInner.this.name);
// error, super cannot be used to access outer class.
// super will always refer the parent, in this case Object
// System.out.println(super.name);
System.out.println(Inner.this.name); // Prints "Sharmi", Inner has declared 'name'
}
}
}
}
/* This is an inner class extending an inner class in the same scope */
class InnerChild extends Inner {
public void doSomething() {
// compiler error, explicit qualifier needed
// 'name' is inherited from Inner, Outer's 'name' is also in scope
// System.out.println(name);
System.out.println(Outer.this.name); // prints "Vel", explicit reference to Outer
System.out.println(super.name); // prints "Sharmi", Inner has declared 'name'
System.out.println(this.name); // prints "Sharmi", name is inherited by InnerChild
}
}
}
class Outer2 {
static String name = "Vel";
static class Inner2 {
static String name = "Sharmi";
class InnerInner2 {
public void doSomething() {
System.out.println(name); // prints "Sharmi", inner-most hides outer-most
System.out.println(Outer2.name); // prints "Vel", explicit reference to Outer2's static variable
// System.out.println(this.name); // error, 'name' is not inherited
// System.out.println(super.name); // error, super refers to Object
}
}
}
}
/* This is a stand-alone class extending an inner class */
class InnerChild2 extends Outer2.Inner2 {
public void doSomething() {
System.out.println(name); // prints "Sharmi", Inner2's name is inherited
System.out.println(Outer2.name); // prints "Vel", explicit reference to Outer2's static variable
System.out.println(super.name); // prints "Sharmi", Inner2 has declared 'name'
System.out.println(this.name); // prints "Sharmi", name is inherited by InnerChild2
}
}
// Example 2
public class InnerTest2 {
public static void main(String s[]) {
new OuterClass().doSomething(10, 20);
// This is legal
// OuterClass.InnerClass ic = new OuterClass().new InnerClass();
// ic.doSomething();
// Compiler error, local inner classes cannot be accessed from outside
// OuterClass.LocalInnerClass lic = new OuterClass().new LocalInnerClass();
// lic.doSomething();
new OuterClass().doAnonymous();
}
}
class OuterClass {
final int a = 100;
private String secret = "Nothing serious";
public void doSomething(int arg, final int fa) {
final int x = 100;
int y = 200;
System.out.println(this.getClass() + " - in doSomething");
System.out.print("a = " + a + " secret = " + secret + " arg = " + arg + " fa = " + fa);
System.out.println(" x = " + x + " y = " + y);
// Compiler error, forward reference of local inner class
// new LocalInnerClass().doSomething();
abstract class AncestorLocalInnerClass { } // inner class can be abstract
final class LocalInnerClass extends AncestorLocalInnerClass { // can be final
public void doSomething() {
System.out.println(this.getClass() + " - in doSomething");
System.out.print("a = " + a );
System.out.print(" secret = " + secret);
// System.out.print(" arg = " + arg); // Compiler error, accessing non-final argument
System.out.print(" fa = " + fa);
System.out.println(" x = " + x);
// System.out.println(" y = " + y); // Compiler error, accessing non-final variable
}
}
new InnerClass().doSomething(); // forward reference fine for member inner class
new LocalInnerClass().doSomething();
}
abstract class AncestorInnerClass { }
interface InnerInterface { final int someConstant = 999;} // inner interface
class InnerClass extends AncestorInnerClass implements InnerInterface {
public void doSomething() {
System.out.println(this.getClass() + " - in doSomething");
System.out.println("a = " + a + " secret = " + secret + " someConstant = " + someConstant);
}
}
public void doAnonymous() {
// Anonymous class implementing the inner interface
System.out.println((new InnerInterface() { }).someConstant);
// Anonymous class extending the inner class
( new InnerClass() {
public void doSomething() {
secret = "secret is changed";
super.doSomething();
}
} ).doSomething();
}
}
Entity | Declaration Context | Accessibility Modifiers | Outer instance | Direct Access to enclosing context | Defines static or non-static members |
Package level class | As package member | Public or default | No | N/A | Both static and non-static |
Top level nested class (static) | As static class member | All | No | Static members in enclosing context | Both static and non-static |
Non static inner class | As non-static class member | All | Yes | All members in enclosing context | Only non-static |
Local class (non-static) | In block with non-static context | None | Yes | All members in enclosing context + local final variables | Only non-static |
Local class (static) | In block with static context | None | No | Static members in enclosing context + local final variables | Only non-static |
Anonymous class (non-static) | In block with non-static context | None | Yes | All members in enclosing context + local final variables | Only non-static |
Anonymous class (static) | In block with static context | None | No | Static members in enclosing context + local final variables | Only non-static |
Package level interface | As package member | Public or default | No | N/A | Static variables and non-static method prototypes |
Top level nested interface (static) | As static class member | All | No | Static members in enclosing context | Static variables and non-static method prototypes |
Chapter 6 - Objects and Classes (Part 4)
No comments:
Post a Comment