Thinking in Java: Chapter 10 Internal classes

Source: Internet
Author: User

10.1 create an internal class
If you want to create an internal class object from any location other than the external class non-static method, you must specify the object type: outerclassname. innerclassname.

10.2 link to external class

When an internal class object is generated, this object is associated with the external object that creates it, so it can access all the members of its peripheral object, no special conditions are required. In addition, the internal class also has access to all elements of the peripheral class.

When an internal class object is created for a peripheral class object, the internal class object will secretly capture a reference pointing to that peripheral class object. Then, when you access the members of this peripheral class, the reference is used to select the members of the peripheral class. Therefore, internal class objects can only be created when they are associated with the objects of the peripheral class (when the internal class is not static ). When constructing an internal class object, you need a reference pointing to its peripheral class object. If the compiler cannot access this reference, an error is returned. But most of the time, there is no need for programmers to worry about it.

 

10.3 use. This and. New

If you need to generate external Class Object references, you can use the external class name followed by the origin and this.

To create an internal class object, you must provide references to other external class objects in the new expression. This requires the. New syntax. As follows:

//: innerclasses/DotNew.java// Creating an inner class directly using the .new syntax.public class DotNew {  public class Inner {}  public static void main(String[] args) {    DotNew dn = new DotNew();    DotNew.Inner dni = dn.new Inner();  }} ///:~

You cannot create an internal class object before you have an external class object. If you create a nested class (static internal class), it does not need to reference external class objects.

10.4 internal class and upward Transformation

When the internal class is transformed to its accumulation, especially to an interface, the internal class can be used. Private internal classes provide a way for class designers to completely block any code dependent on types and completely hide the implementation details.

//: innerclasses/TestParcel.javaclass Parcel4 {  private class PContents implements Contents {    private int i = 11;    public int value() { return i; }  }  protected class PDestination implements Destination {    private String label;    private PDestination(String whereTo) {      label = whereTo;    }    public String readLabel() { return label; }  }  public Destination destination(String s) {    return new PDestination(s);  }  public Contents contents() {    return new PContents();  }}public class TestParcel {  public static void main(String[] args) {    Parcel4 p = new Parcel4();    Contents c = p.contents();    Destination d = p.destination("Tasmania");    // Illegal -- can't access private class:    //! Parcel4.PContents pc = p.new PContents();  }} ///:~

10.5 internal classes in methods and scopes

Internal classes can be defined in a method or in any scope. There are two reasons for doing so:

1) As mentioned above, you have implemented an interface of a certain type, so you can create and return a reference to it.

2) You want to solve a complicated problem and create a class to assist your solution, but you do not want this class to be public-available.

If a class is within the scope of the IF statement, this does not mean that the class is created with conditions. It has actually been compiled with other classes. Then, it is unavailable outside the scope of the class defined; in addition, it is the same as a common class.

10.6 anonymous internal class

When defining a field in an anonymous class, you can also initialize the field. If you define an anonymous internal class and want it to use an object defined externally, the compiler will require its parameter reference to be final. If you forget, A compilation error is returned.

The anonymous internal class cannot have a name constructor, but through instance initialization, you can create a constructor for the anonymous internal class:

//: innerclasses/Parcel10.java// Using "instance initialization" to perform// construction on an anonymous inner class.public class Parcel10 {  public Destination  destination(final String dest, final float price) {    return new Destination() {      private int cost;      // Instance initialization for each object:      {        cost = Math.round(price);        if(cost > 100)          System.out.println("Over budget!");      }      private String label = dest;      public String readLabel() { return label; }    };  }  public static void main(String[] args) {    Parcel10 p = new Parcel10();    Destination d = p.destination("Tasmania", 101.395F);  }} /* Output:Over budget!*///:~

Anonymous internal classes have some limitations compared with the inheritance of formal classes, because anonymous internal classes can expand classes or implement interfaces, but they cannot both. In addition, only one interface can be implemented.

10.7 Nested classes

If you do not need to associate an anonymous internal class with a peripheral class object, you can declare the internal class as static. This is usually called a nested class. When the internal class is static:

1) To create nested class objects, you do not need the objects of its peripheral classes;

2) non-static peripheral class objects cannot be accessed from nested class objects.

There is another difference between a nested class and a common internal class. Fields and methods of common internal classes can only be placed at the external level of the class. Therefore, common internal classes cannot contain static data or static fields, nor Nested classes. But Nested classes can contain all these things.

Class inside the 10.7.1 Interface

Normally, no code can be placed inside the interface, but the nested class can be part of the interface. Any class you place in the interface is automatically static and public.

If you want to create some public code so that they can be shared by all different implementations of an interface, it is convenient to use Nested classes within the interface.

//: innerclasses/ClassInInterface.java// {main: ClassInInterface$Test}public interface ClassInInterface {  void howdy();  class Test implements ClassInInterface {    public void howdy() {      System.out.println("Howdy!");    }    public static void main(String[] args) {      new Test().howdy();    }  }} /* Output:Howdy!*///:~

10.7.2 access members of an external class from a multi-layer nested class

//: innerclasses/MultiNestingAccess.java// Nested classes can access all members of all// levels of the classes they are nested within.class MNA {  private void f() {}  class A {    private void g() {}    public class B {      void h() {        g();        f();      }    }  }}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();  }} ///:~

10.8 why Internal classes are required

The most attractive reason for using internal classes is that each internal class can independently inherit from one (Interface) implementation, so no matter whether the peripheral class has inherited an (Interface) implementation, internal classes are not affected.

If you use an internal class, you can also obtain other features:

1) Internal classes can have multiple instances, each of which has its own status information and is independent of the information of its peripheral class objects;

2) in a single peripheral class, multiple internal classes can implement the same interface in different ways or integrate the same class.

3) the creation of internal class objects does not depend on the creation of peripheral class objects;

4) The internal class has no confusing "Si-a" relationship. It is an independent individual.

10.9 inheritance of internal classes

The problem is that the "secret" reference pointing to the peripheral class object must be initialized.

//: innerclasses/InheritInner.java// Inheriting an inner class.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);  }} ///:~

10.10 can internal classes be overwritten?

When a peripheral class is inherited, there is no magical change in the internal class. These two internal classes are two completely independent entities, each in their own namespace.

//: innerclasses/BigEgg2.java// Proper inheritance of an inner class.import static net.mindview.util.Print.*;class Egg2 {  protected class Yolk {    public Yolk() { print("Egg2.Yolk()"); }    public void f() { print("Egg2.Yolk.f()");}  }  private Yolk y = new Yolk();  public Egg2() { print("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() { print("BigEgg2.Yolk()"); }    public void f() { print("BigEgg2.Yolk.f()"); }  }  public BigEgg2() { insertYolk(new Yolk()); }  public static void main(String[] args) {    Egg2 e2 = new BigEgg2();    e2.g();  }} /* Output:Egg2.Yolk()New Egg2()Egg2.Yolk()BigEgg2.Yolk()BigEgg2.Yolk.f()*///:~

10.11 local internal class

You can create an internal class in a code block. A typical method is to create an internal class in a method body. A local internal class cannot have an access descriptor because it represents a part of the peripheral class, but it can access constants in the current code block and all members of the peripheral class.

10.12 internal Class Identifier

Each class generates a. Class file. The name of the. Class file generated by the internal class has strict rules: the name of the peripheral class, plus "$", and the name of the internal class.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.