Java Tutorial/Class Definition/Nested Classes
Содержание
- 1 An inner class cannot be overriden like a method
- 2 Creating a new nested object outside
- 3 Creating inner classes
- 4 Creating instances of inner classes
- 5 Defining references to inner classes
- 6 Local inner class can have a constructor
- 7 Nested Classes
- 8 Nested classes can access all members of all levels of the classes they are nested within
- 9 Nested classes (static inner classes)
- 10 Nesting a class within a method
- 11 Nesting a class within a scope.
- 12 Proper inheritance of an inner class.
- 13 Putting test code in a nested class
- 14 Returning a reference to an inner class
- 15 Static Nested Classes
- 16 Two ways that a class can implement multiple interfaces
- 17 Using inner classes for callbacks
- 18 With concrete or abstract classes, inner classes are the only way to produce the effect of multiple implementation inheritance.
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>