Thursday, September 9, 2010

Code to Understand Objective Inner Classes

Courtesy of SCJP Sun® Certified Programmer for Java™ 6 Study Guide Exam (310-065) (9780071591065)



/*
Compile this and you will end up with TWO class files

MyOuter.class

MyOuter$MyInner.class
*/

class MyOuter {
   class MyInner { }
}








Instantiating an Inner Class from Within the Outer Class
/*
MyOuter code treats MyInner just as though MyInner were any other accessible class—it instantiates it using the class name (new MyInner()), and then invokes a method on the reference variable (in.seeOuter()). But the only reason this syntax works is because the outer class instance method code is doing the instantiating. In other words, there’s already an instance of the outer class—the instance running the makeInner() method. 
*/

class MyOuter {
   private int x = 7;
   public void makeInner() {
      MyInner in = new MyInner();  // make an inner instance
      in.seeOuter();
   }

   class MyInner {
      public void seeOuter() {
         System.out.println("Outer x is " + x);
      }
   }


   public static void main(String[] args){
      MyOuter outer = new MyOuter();
      outer.makeInner();
   }
}


Creating an Inner Class Object from Outside the Outer Class Instance Code
/*
If we want to create an instance of the inner class, we must have an instance of the outer class. You already know that, but think about the implications...it means that, without a reference to an instance of the outer class, you can’t instantiate the inner class from a static method of the outer class (because, don’t forget, in static code there is no this reference), or from any other code in any other class. Inner class instances are always handed an implicit reference to the outer class. The compiler takes care of it, so you’ll never see anything but the end result—the ability of the inner class to access members of the outer class. The code to make an instance from anywhere outside nonstatic code of the outer class is simple, but you must memorize this for the exam!

You can think of this as though you’re invoking a method on the outer instance, but the method happens to be a special inner class instantiation method, and it’s invoked using the keyword new. Instantiating an inner class is the only scenario in which you’ll invokenew on an instance as opposed to invoking new to construct an instance.
*/

class MyOuter {
   private int x = 7;

   class MyInner {
      public void seeOuter() {
         System.out.println("Outer x is " + x);
      }
   }
   public static void main(String[] args) {
      MyOuter mo = new MyOuter();
// gotta get an instance!
      MyOuter.MyInner inner = mo.new MyInner();
      inner.seeOuter();
   }
}

/*
One-liner implementation.


If we want to create an instance of the inner class, we must have an instance of the outer class. You already know that, but think about the implications...it means that, without a reference to an instance of the outer class, you can’t instantiate the inner class from a static method of the outer class (because, don’t forget, in static code there is no this reference), or from any other code in any other class. Inner class instances are always handed an implicit reference to the outer class. The compiler takes care of it, so you’ll never see anything but the end result—the ability of the inner class to access members of the outer class. The code to make an instance from anywhere outside nonstatic code of the outer class is simple, but you must memorize this for the exam!

You can think of this as though you’re invoking a method on the outer instance, but the method happens to be a special inner class instantiation method, and it’s invoked using the keyword new. Instantiating an inner class is the only scenario in which you’ll invokenew on an instance as opposed to invoking new to construct an instance.
*/

class MyOuter {
   private int x = 7;

   class MyInner {
      public void seeOuter() {
         System.out.println("Outer x is " + x);
      }
   }
   public static void main(String[] args) {
      MyOuter.MyInner inner = new MyOuter().new MyInner();
// if you're into one-liners
      inner.seeOuter();
   }
}



Referencing the Inner or Outer Instance from Within the Inner Class



/*
Within an inner class code, the this reference refers to the instance of the inner class, as you’d probably expect, since this always refers to the currently executing object. But what if the inner class code wants an explicit reference to the outer class instance that the inner instance is tied to? In other words, how do you reference the “outer this”? Although normally the inner class code doesn’t need a reference to the outer class, since it already has an implicit one it’s using to access the members of the outer class, it would need a reference to the outer class if it needed to pass that reference to some other code.
*/

class MyOuter {
   private int x = 7;
   public void makeInner() {
      MyInner in = new MyInner();
      in.seeOuter();
   }
   class MyInner {
      public void seeOuter() {
         System.out.println("Outer x is " + x);
         System.out.println("Inner class ref is " + this);
         System.out.println("Outer class ref is " + MyOuter.this);
      }
   }
   public static void main (String[] args) {
      MyOuter.MyInner inner = new MyOuter().new MyInner();
      inner.seeOuter();
   }
}




No comments:

Post a Comment