I also encountered this situation in the program. Non-static internal classes can directly call member variables of external class instances, but how to reference external class instances has become a problem, the following method solves this problem. See the red code below.
Read a piece of code
Import java. util. Collections list;
Import java. util. List;
Public class OuterClass
{
Private List listeners = new jsonlist ();
Public void addListeners (IListener listener)
{
This. listeners. add (listener );
}
Private OuterClass outer = this; (1)
Private class InnterClass
{
Public void publish ()
{
// Release the event (2)
For (int I = 0; I <listeners. size (); I)
{
IListener listener = (IListener) listeners. get (I );
Listener. receiveEvent (outer );
}
}
}
Public void execute ()
{
InnterClass in = new InnterClass (); (3)
In. publish ();
}
}
Public interface IListener
{
Public void receiveEvent (OuterClass obj );
}
You may think this example is awkward. Where do you feel uncomfortable? In fact, the key to the problem lies in the definition of the interface IListener. The parameter to be passed to the receiveEvent method is an external object! (Don't be excited. I will describe a scenario to be passed in below)
Scenario
In a GUI system, we need to generate a tree on the canvas WorkSpace (WorkSpace implements the IListener Interface), but the generation of each node in the tree (drawing) this is an algorithm we don't know. The system only provides some plotting interfaces for us and returns the element handle! It seems that we need to "Wrap" the painting handle. (actually, I call it a paint Brush because it only knows how to "Brush" the image to get it !) It also provides a general class such as Node.
In this case, the relationship between the Node and the Brush is very subtle, but we can leave these appearances alone, and we can see that the relationship between the Node and the Brush is actually the relationship between the external class and the internal class! -Step 1: confirm the relationship between the two.
However, it is not that simple, and the Node class must handle some events. Of course, only the Brush can understand these events, and the Node does not know the event processing process at all. Now there are two methods: method 1: Let the Node implement all the events of the Brush; Method 2: return the Brush back and let it handle its own events. It seems that method 2 is a good idea, because I don't care about the types of events! -Step 2: Determine the event handling responsibilities
Before you finish, you certainly do not want the canvas WorkSpace to face objects such as the painting handle Brush. On the contrary, you only want WokSpace to know the existence of Node! The parameter of the receiveEvent method in the IListener interface is defined as OuterClass! -Step 3: Define the interface
Public interface IListener
{
Public void receiveEvent (OuterClass obj );
}
Now that this problem is clear (should it be clear ?) How can we achieve such a poor and helpless design? Let's recall that the internal class has the permission to access the methods and attributes of the external class.
Private OuterClass outer = this;-the reference of this external class is prepared for internal class access.
Private class InnterClass
{
Public void publish ()
{
// Release the event
For (int I = 0; I <listeners. size (); I)
{
IListener listener = (IListener) listeners. get (I );
Listener. receiveEvent (outer);-this cannot be returned here, because this represents the internal class itself
}
}