Chapter 10. Inner Classes -- Thinking in Java

1)  It’s possible to place a class definition within another class definition. This is called an inner class.

 

2) If you want to make an object of the inner class anywhere except from within a method of the outer class, you must specify the type of that object as OuterClassName.InnerClassName.

 

3) When you create an inner class, an object of that inner class has a link to the enclosing object that made it, and so it can access the members of that enclosing object—without any special qualifications. In addition, inner classes have access rights to all the elements in the enclosing class. And the enclosing class can also access all members of an inner class.

 

4) The inner class secretly captures a reference to the particular object of the enclosing class that was responsible for creating it. Then, when you refer to a member of the enclosing class, that reference is used to select that member. Fortunately, the compiler takes care of all these details for you, but now you can see that an object of an inner class can be created only in association with an object of the enclosing class (when the inner class is non-static). Construction of the inner-class object requires the reference to the object of the enclosing class, and the compiler will complain if it cannot access that reference. Most of the time this occurs without any intervention on the part of the programmer.

 

5) If you need to produce the reference to the outer-class object, you name the outer class followed by a dot and this.(OuterClassName.this) The resulting reference is automatically the correct type, which is known and checked at compile time.

 

6) Sometimes you want to tell some other object to create an object of one of its inner classes. To do this you must provide a reference to the other outer-class object in the new expression, using the OuterCalssObj.new InnerClassName() syntax.

 

7) If you make a nested class (a static inner class), then it doesn’t need a reference to the outer-class object.

 

8) Inner classes can be created within a method or even an arbitrary scope. There are two reasons for doing this:

    a. You’re implementing an interface of some kind so that you can create and return a reference.
    b. You’re solving a complicated problem and you want to create a class to aid in your solution, but you don’t want it publicly available.

 

9) A class within the scope of a method or an arbitrary scode such as if scope (instead of the scope of another class) is called a local inner class. So it can only be accessed within that method or that scope.

 

10) An anonymous inner class is defined at the time you create an instance of the base class like :

new BaseClass() { //anonymous inner class definition} ;

The semicolon at the end of the anonymous inner class doesn’t mark the end of the class body. Instead, it marks the end of the expression that happens to contain the anonymous class. Thus, it’s identical to the use of the semicolon everywhere else.

 

11) If you’re defining an anonymous inner class and want to use an object that’s defined outside the anonymous inner class ( in its defining scope or method), the compiler requires that the argument reference be final. That also apply to local inner class.

 

12) With instance initialization, you can, in effect, create a constructor for an anonymous inner class.

 

13) If you don’t need a connection between the inner class object and the outer class object, then you can make the inner class static. This is commonly called a nested class.

 

14) A nested class means:
    a. You don’t need an outer class object in order to create an object of a nested class.
    b. You can’t access a non-static outer class object from an object of a nested class.

 

15) Nested classes are different from ordinary inner classes in another way, as well. static fields and methods in ordinary classes can only be at the outer level of a class, so ordinary inner classes cannot have static methods, static fields, nested classes or interfaces. However, nested classes can have all of these. It can be initialized by : new OuterClassName.InnerClassName();

 

16) Normally, you can’t put any code inside an interface, but a nested class can be part of an interface. Any class you put inside an interface is automatically public and static. Since the class is static, it doesn’t violate the rules for interfaces—the nested class is only placed inside the namespace of the interface.

 

17) It's suggested to put a main() in every class to act as a test bed for that class. One drawback to this is the amount of extra compiled code you must carry around. If this is a problem, you can use a nested class to hold your test code (the main() method). The inner class will generate a OuterClassName$InnerClassName.class after compiled. You can use this class for testing, but you don’t need to include it in your shipping product.

 

18) It doesn’t matter how deeply an inner class may be nested—it can transparently access all of the static members of all the classes it is nested within.

 

19) Typically, the inner class inherits from a class or implements an interface, and the code in the inner class manipulates the outer class object that it was created within. So you could say that an inner class provides a kind of window into the outer class.

 

20) The most compelling reason for inner classes is: Each inner class can independently inherit from an implementation. Thus, the inner class is not limited by whether the outer class is already inheriting from an implementation. Without the ability that inner classes provide to inherit—in effect—from more than one concrete or abstract class, some design and programming problems would be intractable. So one way to look at the inner class is as the rest of the solution of the multiple-inheritance problem. Interfaces solve part of the problem, but inner classes effectively allow "multiple implementation inheritance." That is, inner classes effectively allow you to inherit from more than one non-interface.

Comment by Sean, why not use aggregation/composition instead of multiple inheritance?

 

21) If you didn’t need to solve the "multiple implementation inheritance" problem, you could conceivably code around everything else without the need for inner classes. But with inner classes you have these additional features:
    a. The inner class can have multiple instances, each with its own state information that is independent of the information in the outer class object.
    b. In a single outer class you can have several inner classes, each of which implements the same interface or inherits from the same class in a different way.

    c. The point of creation of the inner-class object is tied to the creation of the outer-class object.
    d. There is no potentially confusing "is-a" relationship with the inner class; it’s a separate entity.

 

22) Because the inner-class constructor must attach to a reference of the enclosing class object, things are slightly complicated when you inherit from an inner class. The problem is that the "secret" reference to the enclosing class object must be initialized, and yet in the derived class there’s no longer a default object to attach to. Because the derived class is not an inner class, which does't require a instance of the outer class to instantialize. However the constructor of the derrived class must invoke the contructor of the super class, which is an inner class and needs an instance of its outer class to instanialize. You must use a special syntax to make the association explicitly in the constructor of the derrived class: enclosingClassReference.super();

 

23) Inner class cannot be overriden (constructors are static). If B extends A then A's inner class C can be described as B.C (same as A.C) and can be initilized via new B().new C(). But if B also has an inner class called C then B.C is specific to B's inner class C.

 

24) A local inner class cannot have an access specifier because it isn’t part of the outer class, but it does have access to the final variables in the current code block and all the members of the enclosing class.

 

25) Since the name of the local inner class is not accessible outside the method, the only justification for using a local inner class instead of an anonymous inner class is if you need a named constructor and/or an overloaded constructor, since an anonymous inner class can only use instance initialization. Another reason to make a local inner class rather than an anonymous inner class is if you need to make more than one object of that class.

 

26) If inner classes are anonymous, the compiler simply starts generating numbers as inner class identifiers. If inner classes are nested within inner classes, their names are simply appended after a '$' and the outer class identifier.

你可能感兴趣的:(java,inner class)