Learning Notes 4 (Summary of Internal Classes)

Posted by gregchet on Thu, 04 Jul 2019 23:20:27 +0200

Internal classes are not very well understood, but in fact, one class contains another class.

Just as a person is made up of the brain, limbs, organs and other body results, the internal class is equivalent to one of the organs, such as the heart: it also has its own attributes and behavior (blood, beating).

Obviously, instead of unilaterally representing a heart with attributes or methods, a class is needed.

And the heart is in the human body, just as the inner class is in the outer class.



Example 1: Basic structure of internal classes
//External classes
class Out {
private int age = 12;

//Internal class
class In {
public void print() {
System.out.println(age);
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
//Or access it in the following way
/*
Out out = new Out();
Out.In in = out.new In();
in.print();
*/
}
}
//Operation results: 12


From the above example, it is not difficult to see that internal classes seriously destroy the good code structure, but why use internal classes?

Because internal classes can freely use member variables of external classes (including private ones) instead of generating objects of external classes, this is also the only advantage of internal classes.

Just as the heart has direct access to the body's blood, it doesn't take blood from a doctor.


After compiling, the program will generate two. class files, Out.class and Out$In.class.

Among them, $represents the one in Out.In the program above.

Out.In in = new Out().new In() can be used to generate objects of internal classes. There are two small points of knowledge to be noted in this method.

1. Out begins by indicating which external class objects need to be generated in the internal class

2. Objects of external classes must be present before objects of internal classes can be generated, because the purpose of internal classes is to access member variables of external classes.



Example 2: Variable access form in internal classes

class Out {
private int age = 12;

class In {
private int age = 13;
public void print() {
int age = 14;
System.out.println("Local variables:" + age);
System.out.println("Internal class variables:" + this.age);
System.out.println("External class variables:" + Out.this.age);
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
}
}
//Operation results:

//Local variables: 14
//Internal class variables: 13
//External class variables: 12


From Example 1, it can be found that in the absence of member variables with the same name and local variables, the inner class directly accesses the member variables of the outer class without specifying the name of Out.this.attribute.

Otherwise, local variables in internal classes override member variables in external classes

This. attribute name is used to access the member variables of the inner class itself, and Out.this. attribute name is used to access the member variables of the outer class.



Example 3: Static internal classes

class Out {
private static int age = 12;

static class In {
public void print() {
System.out.println(age);
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out.In();
in.print();
}
}
//Operation results: 12



As you can see, if static is used to static internal, internal classes can only access static member variables of external classes, which has limitations.

Secondly, because internal classes are static, Out.In can be viewed as a whole, and objects of internal classes can be directly new out (it doesn't matter whether external class objects are generated or not by accessing static through class names).



Example 4: Private internal classes

class Out {
private int age = 12;

private class In {
public void print() {
System.out.println(age);
}
}
public void outPrint() {
new In().print();
}
}

public class Demo {
public static void main(String[] args) {
//This method is invalid
/*
Out.In in = new Out().new In();
in.print();
*/
Out out = new Out();
out.outPrint();
}
}
//Operation results: 12



If an internal class only wants to be manipulated by methods in an external class, you can use private to declare the internal class

In the above code, we have to generate an object of Class In in the Out class for operation, instead of using Out. In = new Out (). new In () to generate an object of the inner class.

That is to say, only external classes can control internal classes at this time.

As it is, my heart can only be controlled by my body, and no one else can access it directly.



Example 5: Method inner class

class Out {
private int age = 12;

public void Print(final int x) {
class In {
public void inPrint() {
System.out.println(x);
System.out.println(age);
}
}
new In().inPrint();
}
}

public class Demo {
public static void main(String[] args) {
Out out = new Out();
out.Print(3);
}
}
//Operation results:

3
12

In the above code, we move the inner class to the method of the outer class, and then regenerate an inner class object in the method of the outer class to call the inner class method.

If at this point we need to pass in parameters to methods of external classes, then the method parameters of external classes must be defined using final.

As for final, there is no special meaning here. It's just a form of expression.

Topics: Attribute