Java/Class/Inner Class — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 09:36, 1 июня 2010
Содержание
- 1 Accessing its enclosing instance from an inner class
- 2 A named inner class is used to
- 3 An inner class cannot be overriden like a method
- 4 Compiler will generate a synthetic constructor since SyntheticConstructor() is private
- 5 Creating a constructor for an anonymous inner class
- 6 Creating inner classes
- 7 Creating instances of inner classes
- 8 Demonstrate an Inner Child class
- 9 Demonstrate simple inner class
- 10 Holds a sequence of Objects
- 11 Inheriting an inner class
- 12 Just to show that there is no such thing as inner methods in Java
- 13 Nested classes can access all members of all levels of the classes they are nested within
- 14 Nested Class Static
- 15 Nesting a class within a scope
- 16 Proper inheritance of an inner class
- 17 Putting test code in a nested class
- 18 Returning a reference to an inner class
- 19 This file is to show what happens if you try to access an inner class created in another class
- 20 Using inner classes for callbacks
- 21 With concrete or abstract classes, inner classes are the only way to produce the effect
Accessing its enclosing instance from an inner class
<source lang="java">
public class Main {
private int number = 12; public Main() { InnerClass inner = new InnerClass(); inner.printNumber(); } class InnerClass { public void printNumber() { System.out.println(Main.this.number); } } public static void main(String[] args) { new Main(); }
}
</source>
A named inner class is used to
<source lang="java">
/** Demonstrate inner-inner class. A named inner class
* is used to show that it can access non-local variables * in the enclosing object. */
public class InnerClass3 {
static String msg = "Hello"; public static void main(String[] av) { class Inner { public void doTheWork() { // print member of enclosing class System.out.println(msg); } } Inner p = new Inner(); p.doTheWork(); }
}
</source>
An inner class cannot be overriden like a method
<source lang="java">
// : c08:BigEgg.java // An inner class cannot be overriden like a method. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. class Egg {
private Yolk y; protected class Yolk { public Yolk() { System.out.println("Egg.Yolk()"); } } public Egg() { System.out.println("New Egg()"); y = new Yolk(); }
} public class BigEgg extends Egg {
public class Yolk { public Yolk() { System.out.println("BigEgg.Yolk()"); } } public static void main(String[] args) { new BigEgg(); }
} ///:~
</source>
Compiler will generate a synthetic constructor since SyntheticConstructor() is private
<source lang="java">
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
public class SyntheticConstructor {
private SyntheticConstructor() { } class Inner { // Compiler will generate a synthetic constructor since // SyntheticConstructor() is private. Inner() { new SyntheticConstructor(); } }
}
</source>
Creating a constructor for an anonymous inner class
<source lang="java">
// : c08:AnonymousConstructor.java // Creating a constructor for an anonymous inner class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. abstract class Base {
public Base(int i) { System.out.println("Base constructor, i = " + i); } public abstract void f();
} public class AnonymousConstructor {
public static Base getBase(int i) { return new Base(i) { { System.out.println("Inside instance initializer"); } public void f() { System.out.println("In anonymous f()"); } }; } public static void main(String[] args) { Base base = getBase(47); base.f(); }
} ///:~
</source>
Creating inner classes
<source lang="java">
// : c08:Parcel1.java // Creating inner classes. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class Parcel1 {
class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } // Using inner classes looks just like // using any other class, within Parcel1: public void ship(String dest) { Contents c = new Contents(); Destination d = new Destination(dest); System.out.println(d.readLabel()); } public static void main(String[] args) { Parcel1 p = new Parcel1(); p.ship("Tanzania"); }
} ///:~
</source>
Creating instances of inner classes
<source lang="java">
// : c08:Parcel11.java // Creating instances of inner classes. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class Parcel11 {
class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } public static void main(String[] args) { Parcel11 p = new Parcel11(); // Must use instance of outer class // to create an instances of the inner class: Parcel11.Contents c = p.new Contents(); Parcel11.Destination d = p.new Destination("Tanzania"); }
} ///:~
</source>
Demonstrate an Inner Child class
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
/**
* Demonstrate an Inner Child class * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: InnerChild.java,v 1.3 2004/02/09 03:33:53 ian Exp $ */
public class InnerChild {
public class InnerInnerChild extends InnerChild { } public static void main(String[] argv) { // System.out.println(new InnerChild.InnerInnerChild()); // NOT how! InnerChild x = new InnerChild(); System.out.println(x.new InnerInnerChild()); }
}
</source>
Demonstrate simple inner class
<source lang="java">
/** Demonstrate simple inner class. A named inner class
* is used to show that it can access non-local variables * in the enclosing object. */
public class InnerClass1 {
String msg = "Hello"; void doWork() { Inner i = new Inner(); i.doTheWork(); msg = "Goodbye"; i.doTheWork(); } public static void main(String[] av) { InnerClass1 p = new InnerClass1(); p.doWork(); } class Inner { public void doTheWork() { // print member of enclosing class System.out.println(msg); } }
}
</source>
Holds a sequence of Objects
<source lang="java">
// : c08:LocalInnerClass.java // Holds a sequence of Objects. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. interface Counter {
int next();
} public class LocalInnerClass {
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(); } // The same thing with an anonymous inner class: Counter getCounter2(final String name) { return new Counter() { // Anonymous inner class cannot have a named // constructor, only an instance initializer: { System.out.println("Counter()"); } public int next() { System.out.print(name); // Access local final return count++; } }; } public static void main(String[] args) { LocalInnerClass lic = new LocalInnerClass(); Counter c1 = lic.getCounter("Local inner "), c2 = lic .getCounter2("Anonymous inner "); for (int i = 0; i < 5; i++) System.out.println(c1.next()); for (int i = 0; i < 5; i++) System.out.println(c2.next()); }
} ///:~
</source>
Inheriting an inner class
<source lang="java">
// : c08:InheritInner.java // Inheriting an inner class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. class WithInner {
class Inner { }
} public class InheritInner extends WithInner.Inner {
//! InheritInner() {} // Won"t compile InheritInner(WithInner wi) { wi.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); }
} ///:~
</source>
Just to show that there is no such thing as inner methods in Java
<source lang="java">
/** Just to show that there is no such thing as inner methods in Java */ public class InnerMethods {
public static void main(String[] args) { new InnerMethods().work(); } public void work() { // EXPECT COMPILE ERROR void inner() { System.out.println("Hey, there is such a thing as Inner Methods"); System.out.println("in Java. Better tell James Gosling and Sun!"); } inner(); }
}
</source>
Nested classes can access all members of all levels of the classes they are nested within
<source lang="java">
// : c08:MultiNestingAccess.java // Nested classes can access all members of all levels of the classes they are nested within. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.
public class MultiNestingAccess {
public static void main(String[] args) { MNA mna = new MNA(); MNA.A mnaa = mna.new A(); MNA.A.B mnaab = mnaa.new B(); mnaab.h(); }
} ///:~ class MNA {
private void f() { } class A { private void g() { } public class B { void h() { g(); f(); } } }
}
</source>
Nested Class Static
<source lang="java">
public class NestedClassStatic {
/** Just show that Nested Classes may be static */ static class V { } public static void main(String[] args) { V v = new V(); System.out.println(v); v = new V(); System.out.println(v); }
}
</source>
Nesting a class within a scope
<source lang="java">
// : c08:Parcel5.java // Nesting a class within a scope. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class Parcel5 {
private void internalTracking(boolean b) { if (b) { class TrackingSlip { private String id; TrackingSlip(String s) { id = s; } String getSlip() { return id; } } TrackingSlip ts = new TrackingSlip("slip"); String s = ts.getSlip(); } // Can"t use it here! Out of scope: //! TrackingSlip ts = new TrackingSlip("x"); } public void track() { internalTracking(true); } public static void main(String[] args) { Parcel5 p = new Parcel5(); p.track(); }
} ///:~
</source>
Proper inheritance of an inner class
<source lang="java">
// : c08:BigEgg2.java // Proper inheritance of an inner class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. class Egg2 {
protected class Yolk { public Yolk() { System.out.println("Egg2.Yolk()"); } public void f() { System.out.println("Egg2.Yolk.f()"); } } private Yolk y = new Yolk(); public Egg2() { System.out.println("New Egg2()"); } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); }
} public class BigEgg2 extends Egg2 {
public class Yolk extends Egg2.Yolk { public Yolk() { System.out.println("BigEgg2.Yolk()"); } public void f() { System.out.println("BigEgg2.Yolk.f()"); } } public BigEgg2() { insertYolk(new Yolk()); } public static void main(String[] args) { Egg2 e2 = new BigEgg2(); e2.g(); }
} ///:~
</source>
Putting test code in a nested class
<source lang="java">
// : c08:TestBed.java // Putting test code in a nested class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class TestBed {
public TestBed() { } public void f() { System.out.println("f()"); } public static class Tester { public static void main(String[] args) { TestBed t = new TestBed(); t.f(); } }
} ///:~
</source>
Returning a reference to an inner class
<source lang="java">
// : c08:Parcel2.java // Returning a reference to an inner class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class Parcel2 {
class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } public Destination to(String s) { return new Destination(s); } public Contents cont() { return new Contents(); } public void ship(String dest) { Contents c = cont(); Destination d = to(dest); System.out.println(d.readLabel()); } public static void main(String[] args) { Parcel2 p = new Parcel2(); p.ship("Tanzania"); Parcel2 q = new Parcel2(); // Defining references to inner classes: Parcel2.Contents c = q.cont(); Parcel2.Destination d = q.to("Borneo"); }
} ///:~
</source>
This file is to show what happens if you try to access an inner class created in another class
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.awt.event.*; // This file is to show what happens if you try to access an inner class // created in another class. Here we try to steal ButtonDemo2.java"s // inner class named MyActionListener. You will find that you can"t, // since it has no visible constructor! class ButtonDemo2 {
// Create an inner class which may be named ButtonDemo2$1 Object o = new ActionListener() { public void actionPerformed(ActionEvent evt) { } };
} public class TryStealingInnerClass {
public static void main(String[] a) { new TryStealingInnerClass().doIt(); } public void doIt() { Object o = new ButtonDemo2$1$(); // EXPECT COMPILE ERROR System.out.println(o.toString()); }
}
</source>
Using inner classes for callbacks
<source lang="java">
// : c08:Callbacks.java // Using inner classes for callbacks // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. interface Incrementable {
void increment();
} // Very simple to just implement the interface: class Callee1 implements Incrementable {
private int i = 0; public void increment() { i++; System.out.println(i); }
} class MyIncrement {
void increment() { System.out.println("Other operation"); } static void f(MyIncrement mi) { mi.increment(); }
} // If your class must implement increment() in // some other way, you must use an inner class: class Callee2 extends MyIncrement {
private int i = 0; private void incr() { i++; System.out.println(i); } private class Closure implements Incrementable { public void increment() { incr(); } } Incrementable getCallbackReference() { return new Closure(); }
} class Caller {
private Incrementable callbackReference; Caller(Incrementable cbh) { callbackReference = cbh; } void go() { callbackReference.increment(); }
} public class Callbacks {
public static void main(String[] args) { Callee1 c1 = new Callee1(); Callee2 c2 = new Callee2(); MyIncrement.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
<source lang="java">
// : c08:MultiImplementation.java // With concrete or abstract classes, inner classes are the only way to produce the effect // of "multiple implementation inheritance." // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. class D { } abstract class E { } class Z extends D {
E makeE() { return new E() { }; }
} public class MultiImplementation {
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>