Java Tutorial/Class Definition/Nested Classes

Материал из Java эксперт
Перейти к: навигация, поиск

An inner class cannot be overriden like a method

   <source lang="java">

class A {

 private InnerA y;
 protected class InnerA {
   public InnerA() { System.out.println("A.InnerA()"); }
 }
 public A() {
   System.out.println("New A()");
   y = new InnerA();
 }

} class B extends A {

 public class InnerB {
   public InnerB() { System.out.println("B.InnerB()"); }
 }

} public class MainClass{

 public static void main(String[] args) {
   new B();
 }

}</source>





Creating a new nested object outside

   <source lang="java">

class Outside {

 public class Inside {
 }
 public Outside() {
   Inside inner = new Inside();


 }

}</source>





Creating inner classes

   <source lang="java">

public class MainClass {

 class A {
   private int i = 11;
   public int value() {
     return i;
   }
 }
 class B {
   private String label;
   B(String whereTo) {
     label = whereTo;
   }
   String readLabel() {
     return label;
   }
 }
 // Using inner classes looks just like
 // using any other class, within MainClass:
 public void ship(String dest) {
   A c = new A();
   B d = new B(dest);
   System.out.println(d.readLabel());
 }
 public static void main(String[] args) {
   MainClass p = new MainClass();
   p.ship("AAA");
 }

}</source>





Creating instances of inner classes

   <source lang="java">

public class MainClass {

 class A {
   private int i = 11;
   public int value() {
     return i;
   }
 }
 class B {
   private String label;
   B(String whereTo) {
     label = whereTo;
   }
   String readLabel() {
     return label;
   }
 }
 public static void main(String[] args) {
   MainClass p = new MainClass();
   // Must use instance of outer class
   // to create an instances of the inner class:
   MainClass.A c = p.new A();
   MainClass.B d = p.new B("A");
 }

}</source>





Defining references to inner classes

   <source lang="java">

public class MainClass {

 class A {
   private int i = 11;
   public int value() {
     return i;
   }
 }
 class B {
   private String label;
   B(String whereTo) {
     label = whereTo;
   }
   String readLabel() {
     return label;
   }
 }
 public B to(String s) {
   return new B(s);
 }
 public A cont() {
   return new A();
 }
 public void ship(String dest) {
   A c = cont();
   B d = to(dest);
   System.out.println(d.readLabel());
 }
 public static void main(String[] args) {
   MainClass p = new MainClass();
   p.ship("A");
   MainClass q = new MainClass();
   MainClass.A c = q.cont();
   MainClass.B d = q.to("A");
 }

}</source>





Local inner class can have a constructor

   <source lang="java">

interface Counter {

 int next();

} public class MainClass{

 private int count = 0;
 Counter getCounter(final String name) {
   // A local inner class:
   class LocalCounter implements Counter {
     public LocalCounter() {
       // Local inner class can have a constructor
       System.out.println("LocalCounter()");
     }
     public int next() {
       System.out.print(name); // Access local final
       return count++;
     }
   }
   return new LocalCounter();
 }
 
 public static void main(String[] args) {
   MainClass lic = new MainClass();
   Counter c1 = lic.getCounter("Local inner ");
 }

}</source>





Nested Classes

   <source lang="java">

class Outside {

 public class Inside {
 }

} public class MainClass {

 public static void main(String[] arg) {
   Outside outer = new Outside();
   Outside.Inside inner = outer.new Inside();
 }

}</source>



Nested Classes


Nested classes can access all members of all levels of the classes they are nested within

   <source lang="java">

class MyClass {

 private void f() {}
 class A {
   private void g() {}
   public class B {
     void h() {
       g();
       f();
     }
   }
 }

} public class MainClass {

 public static void main(String[] args) {
   MyClass a = new MyClass();
   MyClass.A innerA = a.new A();
   MyClass.A.B innerb = innerA.new B();
   innerb.h();
 }

}</source>





Nested classes (static inner classes)

   <source lang="java">

public class MainClass {

 private static class ClassA implements A {
   private int i = 11;
   public int value() {
     return i;
   }
 }
 protected static class ClassB implements B {
   private String label;
   private ClassB(String whereTo) {
     label = whereTo;
   }
   public String readLabel() {
     return label;
   }
   // Nested classes can contain other static elements:
   public static void f() {
   }
   static int x = 10;
   static class InnerInnerClass {
     public static void f() {
     }
     static int x = 10;
   }
 }
 public static B dest(String s) {
   return new ClassB(s);
 }
 public static A cont() {
   return new ClassA();
 }
 public static void main(String[] args) {
   A c = cont();
   B d = dest("A");
 }

} interface A {

 int value();

} interface B {

 String readLabel();

}</source>





Nesting a class within a method

   <source lang="java">

public class MainClass {

 public A dest(String s) {
   class B implements A {
     private String label;
     private B(String whereTo) {
       label = whereTo;
     }
     public String readLabel() {
       return label;
     }
   }
   return new B(s);
 }
 public static void main(String[] args) {
   MainClass p = new MainClass();
   A d = p.dest("A");
 }

} interface A {

 String readLabel();

}</source>





Nesting a class within a scope.

   <source lang="java">

public class MainClass {

 private void method(boolean b) {
   if (b) {
     class A {
       private String id;
       A(String s) {
         id = s;
       }
       String getSlip() {
         return id;
       }
     }
     A ts = new A("slip");
     String s = ts.getSlip();
   }
   // Can"t use it here! Out of scope:
   // ! A ts = new A("x");
 }
 public void track() {
   method(true);
 }
 public static void main(String[] args) {
   MainClass p = new MainClass();
   p.track();
 }

}</source>





Proper inheritance of an inner class.

   <source lang="java">

class A {

 protected class InnerA {
   public InnerA() {
     System.out.println("A.InnerA()");
   }
   public void f() {
     System.out.println("A.InnerA.f()");
   }
 }
 private InnerA y = new InnerA();
 public A() {
   System.out.println("New A()");
 }
 public void insertYolk(InnerA yy) {
   y = yy;
 }
 public void g() {
   y.f();
 }

} class B extends A {

 public class InnerB extends A.InnerA {
   public InnerB() {
     System.out.println("B.InnerB()");
   }
   public void f() {
     System.out.println("B.InnerB.f()");
   }
 }
 public B() {
   insertYolk(new InnerB());
 }

} public class MainClass {

 public static void main(String[] args) {
   A e2 = new B();
   e2.g();
 }

}</source>



A.InnerA()
New A()
A.InnerA()
B.InnerB()
B.InnerB.f()


Putting test code in a nested class

   <source lang="java">

public class MainClass {

 public MainClass() {
 }
 public void f() {
   System.out.println("f()");
 }
 public static class Tester {
   public static void main(String[] args) {
     MainClass t = new MainClass();
     t.f();
   }
 }

}</source>





Returning a reference to an inner class

   <source lang="java">

class MyClass {

 private class ClassB implements B {
   private int i = 11;
   public int value() {
     return i;
   }
 }
 protected class ClassA implements A {
   private String label;
   private ClassA(String whereTo) {
     label = whereTo;
   }
   public String readLabel() {
     return label;
   }
 }
 public A dest(String s) {
   return new ClassA(s);
 }
 public B cont() {
   return new ClassB();
 }

} public class MainClass {

 public static void main(String[] args) {
   MyClass p = new MyClass();
   B c = p.cont();
   A d = p.dest("A");
 }

} interface B {

 int value();

} interface A {

 String readLabel();

}</source>





Static Nested Classes

   <source lang="java">

public class Outside {

 public static class Skinside {
 }
 public class Inside {
 }

} public class MainClass {

 public static void main(String[] arg) {
   Outside.Skinside example = new Outside.Skinside();
 }

}</source>





Two ways that a class can implement multiple interfaces

   <source lang="java">

interface A { } interface B { } class X implements A, B { } class Y implements A {

 B makeB() {
   // Anonymous inner class:
   return new B() {
   };
 }

} public class MainClass {

 static void takesA(A a) {
 }
 static void takesB(B b) {
 }
 public static void main(String[] args) {
   X x = new X();
   Y y = new Y();
   takesA(x);
   takesA(y);
   takesB(x);
   takesB(y.makeB());
 }

}</source>





Using inner classes for callbacks

   <source lang="java">

interface InterfaceA {

 void increment();

} class ClassA implements InterfaceA {

 private int i = 0;
 public void increment() {
   i++;
   System.out.println(i);
 }

} class ClassB {

 void increment() {
   System.out.println("Other operation");
 }
 static void f(ClassB mi) {
   mi.increment();
 }

} class ClassC extends ClassB {

 private int i = 0;
 private void incr() {
   i++;
   System.out.println(i);
 }
 private class Closure implements InterfaceA {
   public void increment() {
     incr();
   }
 }
 InterfaceA getCallbackReference() {
   return new Closure();
 }

} class Caller {

 private InterfaceA callbackReference;
 Caller(InterfaceA cbh) {
   callbackReference = cbh;
 }
 void go() {
   callbackReference.increment();
 }

} public class MainClass {

 public static void main(String[] args) {
   ClassA c1 = new ClassA();
   ClassC c2 = new ClassC();
   ClassB.f(c2);
   Caller caller1 = new Caller(c1);
   Caller caller2 = new Caller(c2.getCallbackReference());
   caller1.go();
   caller1.go();
   caller2.go();
   caller2.go();
 }

}</source>





With concrete or abstract classes, inner classes are the only way to produce the effect of multiple implementation inheritance.

   <source lang="java">

class D { } abstract class E { } class Z extends D {

 E makeE() {
   return new E() {
   };
 }

} public class MainClass {

 static void takesD(D d) {
 }
 static void takesE(E e) {
 }
 public static void main(String[] args) {
   Z z = new Z();
   takesD(z);
   takesE(z.makeE());
 }

}</source>