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