Internal classes in Java

Source: Internet
Author: User

Internal classes in Java
Internal classes in Java

To sum up the internal classes, if there are any errors or deficiencies, please share with us.

The definition of internal classes affects the classification of internal classes and internal classes. 1. What is an internal class? Why does an internal class need to be used?

Define a class within a class, that is, an internal class. An internal class provides a window for entering the peripheral class. Each internal class can independently inherit a sub-implementation (interface or abstract class). No matter whether its peripheral class is implemented or not, the internal class has no influence;Implement Multi-InheritanceIn Java, inheritance is a single inheritance and can only inherit from one class. Although multiple interfaces can be implemented, to inherit from multiple classes, only internal classes can be solved, the idea is that the peripheral class inherits one class, and the internal class inherits another class. Although the internal class only inherits one class, however, because it has an implicit reference pointing to a peripheral Class Object (not a static internal class), it can access the members of the peripheral class. If you want to access the methods of the peripheral class, you can define a method to generate a reference to the peripheral class object, which implements "Multi-inheritance ".

2. Classification of internal classes 2.1 common internal classes

Define another class directly in a class, not in a method. An object that creates an internal class cannot be the same as a normal class. Because there is an implicit reference to a peripheral class object, you must first create a peripheral class. As follows (two classes are inherited ):

Package innerclass;/*** common internal class, and implement "Multi-inheritance" * @ author Administrator @ date March 28, 2016 * http://blog.csdn.net/xiaoguobaf */class A {public A () {System. out. println ("class A constructor");} public void f () {System. out. println ("class A f ()") ;}} class B {public B () {System. out. println ("class B constructor");} public void f () {System. out. println ("class B f ()");} class InnerClass extends A {public InnerClass () {System. out. println ("class InnerClass constructor");} // return reference to the peripheral class Object of the generated internal class public B outer () {return B. this ;}}// a typical internal class is created. The peripheral class has a reference method public InnerClass inner () {return new InnerClass () ;}} that returns the internal class object ();}} public class CommonInnerClass {public static void main (String [] args) {B B B = new B (); // create an internal class B through the peripheral class. innerClass ic1 = B. new InnerClass (); // create an internal class through the method of the peripheral class, typical method B. innerClass ic2 = B. inner (); ic1.f (); // use an internal class to access f () ic2.outer () of the peripheral class (). f (); // verify that the reference returned by the outer () method is the reference of the peripheral class of the internal class, and print its hashcode System. out. println (B); System. out. println (ic2.outer () ;}/ ** output: class B constructorclass A constructorclass InnerClass constructorclass A f () class B f () innerclass. B @2a139a55innerclass. B @ 2a139a55 */
2.2 local internal class

The class defined in the method cannot have access specifiers, because it is not part of the peripheral class and belongs to the method containing it. In addition, if you want to use an external-defined object in the internal class, you should modify the object reference to final to prevent modification in the peripheral class.

Package innerclass;/*** local class * @ author Administrator @ date March 28, 2016 * http://blog.csdn.net/xiaoguobaf */interface Counter {int next ();} public class LocalInnerClass {private int count = 0; // The internal class should use name, which is defined as final to prevent the peripheral class from modifying the name Counter getCounter (final String name) {class LocalCounter implements Counter {public LocalCounter () {System. out. println ("LocalCounter constructor");} public int next () {// inheritance, implementation cannot narrow the access scope of System. out. print (name); return count ++;} return new LocalCounter ();} public static void main (String [] args) {LocalInnerClass l = new LocalInnerClass (); counter c = l. getCounter ("LocalInnerClass"); for (int I = 0; I <4; I ++) System. out. println (c. next () ;}}/*** output: LocalCounter constructor LocalInnerClass 0 LocalInnerClass 1 LocalInnerClass 2 LocalInnerClass 3 */
2.3 Anonymous internal class

The anonymous internal class looks like a class definition is suddenly inserted when you create a class object. Because there is no name, there is no constructor. No constructor brings an interesting question. How to initialize it? In the initialization blog, I wrote that before instance initialization, the constructor can use instance initialization as a constructor because the anonymous internal class exists and there is no constructor, instance Initialization is performed before the constructor.

If an internal class only needs an object, it is best to define it as an anonymous internal class. However, there are also disadvantages. An anonymous internal class can only implement one interface or inherit from one class. It cannot implement two interfaces or one interface and inherit from one class because it is anonymous, if two types are allowed, the return type (new) cannot be determined.

Package innerclass;/*** anonymous internal class, in a package, counter Interface has defined * @ author Administrator @ date March 28, 2016 * http://blog.csdn.net/xiaoguobaf */public class AnonymousInnerClass {private int count = 0; Counter getCounter (final String name) {return new Counter () {// instance initialization. Use {System. out. println ("Instance initialization");} public int next () {System. out. print (name); return count ++ ;};} public static void main (String [] args) {AnonymousInnerClass a = new AnonymousInnerClass (); Counter c2 =. getCounter ("Anonymous inner"); for (int I = 0; I <4; I ++) System. out. println (c2.next () ;}}/*** output: Instance initialization Anonymous inner 0 Anonymous inner 1 Anonymous inner 2 Anonymous inner 3 */
2.4 static internal class

Also known as nested class (note that it is not a nested class ). The static modifier is added before the definition of the internal class. In this case, the static internal class is not associated with the peripheral class. To create an object of the static internal class, you do not need to create an object of the peripheral class first, it cannot access non-static peripheral class objects, also known as Nested classes.

Apart from the above, the differences between static internal classes and common internal classes cannot be modified by static members or methods of common internal classes. This is a compilation problem. Let's start with static member variables. static member variables are initialized during class loading, that is, the first time a class object is created or static member variables are accessed, it has a definite location in the memory distribution of the class. For internal classes, its memory allocation is similar to that of non-static member variables, and no peripheral class objects are created, the value of the member variable is uncertain, so the memory location is not determined, and the memory location of the peripheral class object is not determined, so the referenced memory location cannot be determined, the creation of common internal classes depends on the creation of peripheral class objects. Therefore, common internal classes cannot have static modified member variables and methods.

Package innerclass;/*** static internal class * @ author Administrator @ date March 28, 2016 * http://blog.csdn.net/xiaoguobaf */interface Contents {int value ();} interface Destination {String readLabel ();} public class NestedClass {private static class ParcelContents implements Contents {private int I = 11; public int value () {return I;} void printf () {System. out. println ("ParcelContents:" + I) ;}} protected static class ParcelDestination implements Destination {private String label; private ParcelDestination (String label) {this. label = label;} public String readLabel () {return label;} public static void f () {} static int x = 10; static class AnotherLevel {static int x = 10; public static void f () {}} public static Destination destination (String s) {return new ParcelDestination (s);} public static Contents contents () {return new ParcelContents ();} public static void main (String [] args) {Contents c = contents (); Destination d = destination ("Yanni"); c. value ();}}

This routine still needs to be analyzed in some places, and the internal class behind it is transformed up.

The internal class of the interface, that is, the class defined in the interface. Any class in the interface is implicitly public and static. For example:

Package innerclass;/*** interface internal class * @ author Administrator @ date March 28, 2016 * http://blog.csdn.net/xiaoguobaf */public interface ClassInsideInterface {void howdy (); class Test implements ClassInsideInterface {@ Override public void howdy () {System. out. println ("howdy");} public static void main (String [] args) {new Test (). howdy ();}}}

The compiler will not report an error. The internal class of the interface can be used to implement the public code of the interface. This code can be shared by different implementations.

Write a test for each class. You do not need to write each nested class.

3. Internal class problems internal class and upward Transformation
Transform the internal class to the base class, especially the interface. The Implementation Details of the internal class are hidden and invisible. If the internal class is private, in this case, the non-peripheral category cannot be transformed downward. It can be said that the internship details Completely hidden.
Package innerclass;/*** internal class and upward transformation * @ author Administrator @ date March 29, 2016 * http://blog.csdn.net/xiaoguobaf */public class InnerClassAndUpcasting {private class ParcelContents implements Contents {private int I = 11; public int value () {return I;} // The default value is private. It is useless with the class. It works with the public interface and is converted to the interface type upwards, the void printf () {System. out. println ("ParcelContents:" + I) ;}// it can be accessed only in InnerClassAndUpcasting. It has no special features and can be accessed in the protected modified class, but it is not necessary, public void callPrintf () {printf () ;}} protected class ParcelDestination implements Destination {private String label; private ParcelDestination (String label) {this. label = label;} public String readLabel () {return label;} public Destination destination (String s) {return new ParcelDestination (s);} public Contents contents () {return new ParcelContents ();} public static void main (String [] args) {InnerClassAndUpcasting inau = new InnerClassAndUpcasting (); Contents c = inau. contents (); Destination d = inau. destination ("Yanni"); // you must first perform a downward transformation to access the child type method. Because the extension information is inherited, the parent class cannot access the extension information in the subclass. // c. printf (); // The prompt method is not defined (ParcelContents) c ). printf (); (ParcelContents) c ). callPrintf (); d. readLabel () ;}/ *** there can be two main functions in a class file, but eclipse will prompt you which one to execute during execution, I am here to facilitate the Test * @ author Administrator @ date March 29, 2016 * http://blog.csdn.net/xiaoguobaf */class Test {public static void main (String [] args) {InnerClassAndUpcasting inau1 = new InnerClassAndUpcasting (); contents c1 = inau1.contents (); System. out. println (c1.value (); // It cannot be transformed downward. Since the ParcelContents class is private, its peripheral class InnerClassAndUpcasting is generated and cannot be accessed // (ParcelContents) c ). printf () ;}/ *** output: ParcelContents: 11 ParcelContents: 1111 */

Multi-layer nested internal class access
The multi-layer nested internal class can transparently access all the members of the peripheral class embedded by it. It is easy to understand, because there are references to the peripheral class (non-static ), static internal classes can be understood as the same as static member variables, from the memory perspective. Internal class inheritance
Internal classes can be inherited. The syntax is special because the reference to the peripheral class must be initialized (non-static ).
Package innerclass;/*** internal class inheritance * @ author Administrator @ date March 29, 2016 * http://blog.csdn.net/xiaoguobaf */class WithInner {class Inner {}} public class InnerClassInheriting extends WithInner. inner {InnerClassInheriting (WithInner wi) {wi. super () ;}public static void main (String [] args) {WithInner wi = new WithInner (); InnerClassInheriting ic = new InnerClassInheriting (wi );}}

Can internal classes be overwritten?
Internal classes cannot be overwritten, just like defining members with the same name and attributes in the parent class and subclass, they are different.

Internal classes, closures, and callbacks
A closure is an callable object. Its information comes from creating its scope. An internal class is an object-oriented closure because it contains information about peripheral class objects, by default, a (non-static) Reference pointing to a peripheral class object is also available.
Callback: in simple words, you call me. I will call you and write it here first. Looking at TIJ, I still think the above example is a bit about the Strategy Mode. Some results of the query are about the observer mode.

 

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.