[ Pobierz całość w formacie PDF ]
.out.println("BigEgg.Yolk()");}}public static void main(String[] args) {new BigEgg();}} ///:~The default constructor is synthesizedautomatically by the compiler, and this calls the base-class defaultconstructor.You might think that since a BigEgg is being created, the“overridden” version of Yolk would be used, but this is notthe case.The output is:[ Add Comment ]New Egg()Egg.Yolk()This example simply shows that thereisn’t any extra inner class magic going on when you inherit from the outerclass.The two inner classes are completely separate entities, each in their ownnamespace.However, it’s still possible to explicitly inherit from theinner class:[ Add Comment ]//: c08:BigEgg2.java// Proper inheritance of an inner class.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();}} ///:~Now BigEgg2.Yolk explicitlyextends Egg2.Yolk and overrides its methods.The methodinsertYolk( ) allows BigEgg2 to upcast one of its own Yolkobjects into the y reference in Egg2, so when g( )calls y.f( ) the overridden version of f( ) is used.Theoutput is:Egg2.Yolk()New Egg2()Egg2.Yolk()BigEgg2.Yolk()BigEgg2.Yolk.f()The second call toEgg2.Yolk( ) is the base-class constructor call of theBigEgg2.Yolk constructor.You can see that the overridden version off( ) is used when g( ) is called.[ Add Comment ]Inner class identifiersSince every class produces a.classfile that holds all the information about how to create objects of this type(this information produces a “meta-class” called the Classobject), you might guess thatinner classes must also produce.class files to contain the information for their Classobjects.The names of these files/classes have a strict formula: the name of theenclosing class, followed by a ‘$’, followed by the name ofthe inner class.For example, the.class files created byInheritInner.java include:InheritInner.classWithInner$Inner.classWithInner.classIf inner classes are anonymous, thecompiler simply starts generating numbers as inner class identifiers.If innerclasses are nested within inner classes, their names are simply appended after a‘$’ and the outer class identifier(s).[ Add Comment ]Although this scheme of generatinginternal names is simple and straightforward, it’s also robust and handlesmostsituations[42].Since it is the standard naming scheme for Java, the generated files areautomatically platform-independent.(Note that the Java compiler is changingyour inner classes in all sorts of other ways in order to make them work.)[ Add Comment ]Why inner classes?At this point you’ve seen a lot ofsyntax and semantics describing the way inner classes work, but thisdoesn’t answer the question of why they exist.Why did Sun go to so muchtrouble to add this fundamental language feature?[ Add Comment ]Typically, the inner class inherits froma class or implements an interface, and the code in the inner classmanipulates the outer class object that it was created within.So you could saythat an inner class provides a kind of window into the outer class
[ Pobierz całość w formacie PDF ]