Java Tutorial/Class Definition/Nested Classes

Материал из Java эксперт
Версия от 05:00, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

An inner class cannot be overriden like a method

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();
  }
}





Creating a new nested object outside

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

    
  }
}





Creating inner classes

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");
  }
}





Creating instances of inner classes

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");
  }
}





Defining references to inner classes

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");
  }
}





Local inner class can have a constructor

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 ");
  }
}





Nested Classes

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



Nested Classes


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

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();
  }
}





Nested classes (static inner classes)

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();
}





Nesting a class within a method

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();
}





Nesting a class within a scope.

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();
  }
}





Proper inheritance of an inner class.

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();
  }
}



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


Putting test code in a nested class

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();
    }
  }
}





Returning a reference to an inner class

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();
}





Static Nested Classes

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();
  }
}





Two ways that a class can implement multiple interfaces

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());
  }
}





Using inner classes for callbacks

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();
  }
}





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

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());
  }
}