Many people may not be familiar with Java inner classes. In fact, a similar concept exists in C++, that is, nested classes. The differences and connections between the two will be compared below. On the surface, an inner class is just another class defined within the class (as you will see below, inner classes can be defined in many places), but in fact it is not that simple. At first glance, inner classes seem a bit redundant. The usefulness may not be so obvious to beginners, but with a deeper understanding of it, you will find that the designers of Java do have good intentions in internal classes. Learning to use inner classes is part of mastering advanced Java programming, which allows you to design your program structure more elegantly. Let’s introduce it from the following aspects:
first meeting
Copy the code code as follows:
public interface Contents {
int value();
}
public interface Destination {
String readLabel();
}
public class Goods {
private class Content implements Contents {
private int i = 11;
public int value() {
return i;
}
}
protected class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
public Destination dest(String s) {
return new GDestination(s);
}
public Contents cont() {
return new Content();
}
}
class TestGoods {
public static void main(String[] args) {
Goods p = new Goods();
Contents c = p.cont();
Destination d = p.dest("Beijing");
}
}
In this example, classes Content and GDestination are defined inside class Goods, and have protected and private modifiers respectively to control access levels. Content represents the content of Goods, and GDestination represents the destination of Goods. They implement two interfaces Content and Destination respectively. In the following main method, you directly use Contents c and Destination d to operate. You don't even see the names of these two internal classes! In this way, the first benefit of inner classes is to hide operations that you don't want others to know, that is, encapsulation.
At the same time, we also discovered the first way to get an inner class object outside the scope of the outer class, which is to create and return it using the methods of its outer class. The cont() and dest() methods in the above example do this. So is there any other way?
Of course there is,
the syntax format is as follows:
outerObject=new outerClass(Constructor Parameters);
outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);
Note that when creating a non-static inner class object, you must first create the corresponding outer class object. As for the reason, this leads to our next topic. Non-static inner class objects have references to their outer class objects.
Slightly modify the previous example:
Copy the code code as follows:
public class Goods {
private int valueRate = 2;
private class Content implements Contents {
private int i = 11 * valueRate;
public int value() {
return i;
}
}
protected class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
public Destination dest(String s) {
return new GDestination(s);
}
public Contents cont() {
return new Content();
}
}
Here we add a private member variable valueRate to the Goods class, which means the value coefficient of the goods. It is multiplied by it when the value() method of the internal class Content calculates the value. We found that value() can access valueRate, which is the second benefit of inner classes. An inner class object can access the contents of the outer class object that created it, even private variables! This is a very useful feature that provides us with more ideas and shortcuts when designing. To achieve this function, the inner class object must have a reference to the outer class object. When the Java compiler creates an inner class object, it implicitly passes the reference to its outer class object and keeps it. This allows the inner class object to always access its outer class object, and this is also why to create an inner class object outside the scope of the outer class, you must first create its outer class object.
Some people may ask, what should I do if a member variable in the inner class has the same name as a member variable in the outer class, that is, the member variable of the outer class with the same name is blocked? It’s okay. Java uses the following format to express references to external classes:
outerClass.this
With it, we are not afraid of this shielding situation.
static inner class
Like ordinary classes, inner classes can also be static. However, compared with non-static inner classes, the difference is that static inner classes have no external references. This is actually very similar to nested classes in C++. The biggest difference between Java internal classes and C++ nested classes is whether there are references to the outside. Of course, from a design perspective and some of its details, There is a difference.
In addition, in any non-static inner class, there cannot be static data, static methods or another static inner class (inner classes can be nested more than one level). But you can have all this in static inner classes. This can be regarded as the second difference between the two.
local inner class
Yes, Java inner classes can also be local, they can be defined within a method or even a code block.
Copy the code code as follows:
public class Goods1 {
public Destination dest(String s) {
class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
return new GDestination(s);
}
public static void main(String[] args) {
Goods1 g = new Goods1();
Destination d = g.dest("Beijing");
}
}
The above is one such example. In the method dest, we define an inner class, and finally this method returns the object of this inner class. If we only need to create an object of an inner class and create it to the outside, we can do this. Of course, inner classes defined in methods can diversify the design, and their uses are not limited to this.
Here's an even weirder example:
Copy the code code as follows:
public class Goods2 {
private void internalTracking(boolean b) {
if (b) {
class TrackingSlip {
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() {
return id;
}
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
}
public void track() {
internalTracking(true);
}
public static void main(String[] args) {
Goods2 g = new Goods2();
g.track();
}
}
You can't create an object of this inner class outside the if, because it goes beyond its scope. However, during compilation, the internal class TrackingSlip is compiled at the same time as other classes, except that it has its own scope and is invalid beyond this scope. Other than that, it is no different from other internal classes.
anonymous inner class
The syntax rules of Java's anonymous inner classes may seem a bit weird, but like anonymous arrays, when you only need to create an object of a class and don't need its name, using inner classes can make the code look concise and clear. Its syntax rules are as follows:
new interfacename(){......}; or new superclassname(){......};
Let’s continue with the example below:
Copy the code code as follows:
public class Goods3 {
public Contents cont() {
return new Contents() {
private int i = 11;
public int value() {
return i;
}
};
}
}
The method cont() here uses an anonymous inner class to directly return an object of a class that implements the Contents interface, which looks very simple indeed.
In anonymous adapters for Java event processing, anonymous inner classes are widely used. For example, when you want to close the window, add this code:
Copy the code code as follows:
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
One thing to note is that since the anonymous inner class has no name, it has no constructor (but if the anonymous inner class inherits a parent class that only contains a parameterized constructor, it must bring these parameters when creating it, and Use the super keyword to call the corresponding content during the implementation process). If you want to initialize its member variables, there are several methods:
If it is in an anonymous inner class of a method, you can use this method to pass in the parameters you want, but remember, these parameters must be declared final.
Transform the anonymous inner class into a named local inner class so that it can have a constructor.
Use an initialization block in this anonymous inner class.
Why do you need inner classes?
What are the benefits of java inner classes? Why do you need inner classes?
First, let's take a simple example. If you want to implement an interface, but a method in this interface has the same name and parameters as a method in the class you conceived, what should you do? At this time, you can build an inner class to implement this interface. Since the inner class is accessible to everything in the outer class, doing so will accomplish all the functionality you would have if you implemented the interface directly.
But you may want to question, wouldn't it be enough to just change the method?
Indeed, using this as a reason for designing internal classes is really unconvincing.
The real reason is this. Together, the internal classes and interfaces in Java can solve a problem that C++ programmers often complain about in Java without multiple inheritance. In fact, C++'s multiple inheritance is very complicated to design, and Java can achieve the effect of multiple inheritance very well through internal classes and interfaces.