God perspective JAVA - Basic 08 - category 06 [2021-08-07]

1. Abstract classes and methods

When we talked about polymorphism earlier, we talked about when the Animal class is inherited by Cat class and Dog class. Suppose Pig class and Bird class inherit again...

These classes, which are a little more specific than the Animal class Animal, inherit the Animal class. The Animal class has a speak method, and then each subclass overrides this method.

When polymorphism is used, although the variable of Animal type is received, new is indeed a subclass. Although the name of the speak method in the Animal class is executed, the logic executed is the speak method logic rewritten in the subclass of new. At this time, we found that the speak logic in the Animal class is not needed at all. We just need this name to unify the specification. Everyone rewrites it.

When a method in a class does not directly define a function body, this method is an abstract method. A class containing abstract methods is an abstract class.

The emergence of abstract classes is the law we find when we actually write code. Sometimes, the public methods extracted from subclasses are transferred to the base class. The base class only needs to define the method name, and the specific implementation can be rewritten by subclasses. In this way, the word abstraction naturally appears. Abstract means that there is no concrete implementation.

From the above, it can be concluded that abstract methods must be inherited, otherwise they are meaningless! Therefore, abstract methods cannot be private or static, because static is a class and cannot be inherited. Methods or classes cannot be modified at the same time as final. Classes modified by final cannot be inherited, and methods cannot be overridden.

The abstract keyword is abstract

abstract can only modify classes and methods.

public abstract class Animal {
    
    public abstract void speak();
}
  • Abstract classes can have no abstract methods.

  • Classes with abstract methods must be modified with abstract, that is, classes with abstract methods must be abstract classes.

Let's guess what abstract did.

1. Abstract modifier, which tells the compiler that I am abstract. You don't check my function body.

2. Abstract modifier class is to tell the compiler that I can define abstract methods. Don't stop me from defining abstract methods. For the method without function body defined internally, check whether the abstract modifier is used.

3. Abstract modifies a class to tell the compiler that this class cannot be created with new, that is, it cannot instantiate an object. The parent class itself, that is, the current abstract class, is not used for new, but to receive the objects from the subclass new.

Since an abstract class cannot be a new object, is there a constructor?

It must be called when subclasses inherit. Otherwise, how to copy the parent class. This also proves that calling constructor and instantiating object are two things!

Talking about abstraction and not polymorphism is playing hooligans.

Defining abstract classes is like defining rules and standards. The specific implementation is given to the subclass that inherits it.

There are two subclasses that inherit it.

1. Only partially overridden abstract methods.

Only the subclasses of some abstract methods are rewritten, indicating that there are also abstract methods in them. This is also an abstract class! Cannot instantiate object

2. All the abstract methods are rewritten.

Rewrite all abstract methods. This is not an abstract class. You can use a new object. Moreover, in order to reflect the role of abstract classes, we have to use polymorphic writing and receive them with abstract classes. Receiving with your own class will lose the meaning of the abstract class definition! But it can be received with its own type. Abstraction is further evolved from polymorphism.

2. Anonymous class

We talked about anonymous objects earlier, that is, new an object, but this object does not assign a value to a variable of a class type, that is, it does not take a name.

It is generally used to pass arguments directly to methods. See anonymous objects for details.

Anonymous classes are actually similar. It is also a class that does not take a name and can be used directly. See the following code:

// There is an abstract class Animal
public abstract class Animal {
    // Abstract method speak
    public abstract void speak();
}
​
@Test
public void test1(){
    // The parameter of testFunc passes an anonymous class
    testFunc(new Animal() {
        @Override
        public void speak() {
            System.out.println("Anonymous classes, using");
        }
    });
}
// Method, the parameter is of type Animal
private void testFunc(Animal ani){
    ani.speak();
}

The code above shows the use of anonymous classes.

// Definition of anonymous class
new Animal() {
    @Override
    public void speak() {
    System.out.println("Anonymous classes, using");
    }
}

The Animal class is an abstract class and cannot directly new objects. But look at the anonymous class. Its use form does have new Animal(). Is this contradictory?

No, because you should not ignore the curly braces. There is an override of the abstract method speak in braces.

When will rewriting occur? Subclasses, we only talked about subclasses inheriting the parent class. You can re-establish the methods in the parent class.

So this anonymous class is actually a subclass of animal. Why use new Animal() {...} What about this? Because this is an anonymous class, you can't create an object with new's own name. You can only use the of the parent class. Moreover, when subclassing a new object, it will implicitly call the super method, that is, the constructor of the parent class. Animal () is actually the construction method of animal.

When you use the name of the parent class for a new object, you must follow {} and override the abstract method inside. This is the anonymous subclass of new.

Anonymous classes, like anonymous methods, can only be used once. Because there is no name, they can't be found later and will be garbage collected.

3. Template method design pattern

In fact, we have already reasoned about this design pattern. Is the application of polymorphism.

Abstract class is the parent class, which defines abstract methods. Is the method that all subclasses need to implement. The method in the parent class is actually the definition standard, that is, the names of all subclasses must be consistent with the rewritable method names defined by the parent class.

Abstract classes do not specify that all methods must be abstract methods, or even all non abstract methods. Some abstract methods are OK.

When we solve a problem, some steps need to be determined according to the specific situation, but the step name is determined. You can define it as an abstract method, put subclasses to rewrite, and improve the logic.

public abstract class Animal {
    // Abstract method
    public abstract void speak();
    
    // practical problem 
    public void spendTime(){
        long start = System.currentTimeMillis();
        speak();
        long end = System.currentTimeMillis();
        System.out.println("Cost:"+ (end - start)+"Such a long time!");
    }
}
// A non Abstract subclass
public class Dog extends Animal{
    public String type = "Dog";
​
    @Override
    public void speak(){
        System.out.println(this.type);
    }
}
​
// use
@Test
public void test1(){
    Animal dog = new Dog();
    testFunc(dog);
}
private void testFunc(Animal ani){
    ani.spendTime();
}
​

In the above code, the actual problem is to find out how long the speak method has been executed. This speak() has to be determined according to the specific subclass implementation. But the overall steps are determined. That is, the logic of the spendTime method is deterministic.

Define speak as an abstract method. A subclass Dog inherits the Animal class and implements the speak method.

When we receive the new Dog with the parent class in polymorphic writing, it is passed to testFunc. It's OK to call the spendTime method in Animal in Func. The speak method called in the spendTime method is actually the speak method overridden in Dog class. This is the polymorphism and method rewriting mentioned before.

What is the difference between this and the past?

In the past, testFunc was an abstract method speak of the parent class that was called directly. Now it is a method spendTime that contains an abstract method in the parent class. It is to add a little logic to the speak method, wrap the abstract speak method, and turn it into a spendTime method containing the speak method. The essence is the same.

This pattern is actually an application of polymorphism.

4. Interface interface

Why do I need an interface?

Interfaces and classes in JAVA are at the same level. Have you found that the definition of an abstract class is that the methods in it can be abstract or not, but the class containing an abstract method must be an abstract class. The methods in this abstract class are not defined. That is, some methods can be non Abstract!

The interface is upgraded.

1. All methods must be abstract! Specify that all methods in my class are abstract, that is, I no longer provide methods with function bodies. The methods defined by this class are a standard and specification. Subclasses have to be overridden according to the defined method name.

2. The interface has also been upgraded. All classes that inherit the interface must override the abstract methods inside. Subclasses of abstract classes do not have this provision.

3. Class also has a provision that the class must be single inheritance. The interface breaks through this limitation and can inherit more. In other words, in order to provide the requirement of multi inheritance, it does not conflict with the class. The function of multi inheritance is given to the interface.

When these conditions are met, the abstract class is upgraded and renamed interface.

Must all methods of the interface be abstract?

This is true before JAVA 8. After jdk8, the interface also allows the definition of methods with function bodies. However, these methods with function bodies are limited. They must be default methods or static methods. After JDK9, the interface has added the feature that private methods can be defined.

It can be seen that the language is developing, and JAVA designers can't completely design a language at the beginning. It needs continuous improvement in practice. However, the premise of improvement is not to destroy the original function. This is why it was previously stipulated that the methods in the interface must be abstract and can be inherited (implemented). After JAVA 9, it was stipulated that you can define non abstract methods, which must be default methods, static methods and private methods.

Analysis: the origin of the default method.

public interface Demo1 {
    // The first is the definition of the default method, using default
    public default void method2(){
        System.out.println("Hello");
    }
}

The methods in the interface analyzed above must be abstract and can be inherited and rewritten. And to rewrite it all. If an abstract method is suddenly added to the interface due to business requirements. Then many classes that inherit (implement) it will report errors, because there is another abstract method that has not been implemented.

To solve this problem, the default method appears. This default method does not require subclasses to override because it has its own method body. Subclasses can also be overridden.

Collection There are default methods in the interface. as stream,parallelStream,spliterator,removeIf
Collection Inherited Iterable Interface, and override spliterator method. You don't see that an interface can also override the methods of the parent interface. The premise is that it must be defined as the default method. Because static methods cannot be inherited, only the default methods can have method bodies.

Static method:

Static methods are relatively simple. For static methods, the ownership of the code changes. This method will belong to the interface, not the object. It cannot be inherited (implemented) and can only be called through the interface name point. It is also a little different from the static method of the class. Ordinary classes can be instantiated, so the static method of the class can be instantiated through the object of the class. However, the interface cannot instantiate the object. It can only be accessed through the interface name.

The emergence of static methods is also found in practice. Sometimes there are some public methods. It is appropriate to extract to the interface

Private method:

Skip it for the time being. Content belonging to JDK9. This tutorial is for JDK8 and below.

4.1 interface properties

Attributes in interfaces can only be global constants. According to the appearance of interfaces, they are more abstract than abstract classes and must be inherited and implemented by subclasses. You cannot instantiate an object yourself.

The object cannot be instantiated, which means that the properties in the interface cannot be called by their own objects. Can only be called by objects of subclasses. Therefore, the attributes in the interface must be inherited, not private. You cannot instantiate an object yourself. If you want to use the interface yourself, you must define it as static.

The methods in the interface have now become specifications. Therefore, attributes either do not exist or become a specification. That is, the specification is defined. You can only use it and cannot change it. It should also be defined as final

Therefore, the initial interface attribute is defined as public static final. Translation means that it can be inherited and accessed through the interface name. Subclasses can only be used and cannot be changed

4.3 discussion on interfaces and classes

4.3. Does the 1 interface have a constructor?

There is no constructor in the interface. Because the interface is very abstract. Cannot instantiate object. And supports multiple inheritance. The JAVA designer took the construction method.

However, subclasses still need to inherit and override abstract methods. Doesn't it mean that subclasses will call the constructor of the parent class by default?

Yes, that's inheritance. Now that there is no constructor, the subclass inheritance interface will no longer be called inheritance. It's called implementation.

In order to explain the reason, inheritance and implementation are assimilated. In fact, there are differences.

The subclass inheritance interface is renamed implementation! Inheritance in the interface refers to implementation. The relationship between class and interface has no inheritance, only implementation!!!

The reason is that the implementation will not call the constructor of the interface by default, because the interface has no constructor!

4.3. 2 Relationship between interface and class

The inherited keyword is extends, and the implementation is called implements

Correction: in this article, the above statement about class inheritance interface is actually wrong. The correct one should be class implementation interface. Inheritance is for comparison with class inheritance. In fact, there is little difference between interface implementation and class inheritance. Inheritance calls the constructor of the parent class by default, and the implementation does not. The rest are the same.

Class to class relationship: inheritance, and single inheritance

Relationship between class and interface: implementation is the implementation interface of class.

Relationship between interfaces: inheritance, and multiple inheritance is allowed.

The same type is called inheritance, and the class and interface are called implementation.

Multiple implementations of interfaces:

This is nothing new. It was meant to be like this. In polymorphism, the parent class is inherited by many subclasses, and each subclass overrides the parent class method. Slowly find that the inherited method of the parent class does not need the method body, which leads to the abstract method and the abstract class. Abstract classes are not thorough enough. Here comes the interface.

This evolution process is only the evolution of the parent class. In essence, there are many subclasses to inherit. Of course, the interface is called implementation.

Without multiple implementation classes to implement the interface, there is no polymorphism of the interface.

Note: Inheritance and implementation can exist at the same time.

Question: when the parent class inherited by the implementation class and the implemented interface have methods with the same name and parameters, and the implementation class does not override this method, which one is called?

When this method is not the default method in the interface, that is, the interface definition before JDK7 has no method body and is an abstract method. If this method in the parent class is an abstract method, it must be rewritten to inherit this method. It is not an abstract method without rewriting description. That is, this method has a method body. Therefore, this case is the method of the parent class called.

JDK8 adds a default method, but it can't change the calling principle. Looks like class first.

4.3. 3 why does the interface support multiple inheritance (Implementation)?

Let's see why classes don't support multiple inheritance. Hypothesis support.

A class a inherits three classes B, C and D at the same time. B. Both C and d have the speak method.

When A does not override the speak method, A instantiates an object and calls the speak method. Which class does it call?

B or C or D?

This problem is solved by algorithm, but it is very complex. C + + supports multiple inheritance, and python also supports it. You can refer to it.

Here, if you can't determine which method is called, it will bring uncertainty to the execution result. JAVA prohibits this situation.

So why is the interface allowed?

The biggest reason is that the methods of the interface are very abstract. All methods before 1.7 must be abstract. There is no function body.

The implementation class must override the methods in the interface.

Look at this situation: A class A implements three interfaces B, C and D at the same time. All three interfaces have A speak abstract method.

Since A must override speak, it must call its own logic. There is no multi inheritance of classes.

Even if the abstract methods of three interfaces B, C and D have the same name, it doesn't matter. Anyway, there is no method body, and they will be rewritten by a method with the same name.

In this way, multi inheritance of interfaces becomes a simple abstract method combination of interfaces. Multiple abstract methods with the same name are equivalent to one effective method.

Java 8's interface supports default methods, which brings some new problems.

Question: when there are default methods with the same name and parameters in B, C and D implemented by the implementation class, which interface default method does the implementation class A call when calling this method?

ans: the default method of the interface does not require the implementation class to be rewritten. But in this case, it must be rewritten. Otherwise there will be conflict. I don't know which interface to call.

When rewritten, it is called to rewrite itself, not in the interface.

Go further: if you also inherit class E, and there are methods with the same name and parameters in E, how do you call them?

ans: it's easier at this time. See the class priority principle above. Is to call this method in parent class E. And subclasses do not require overriding.

Of course, if the implementation class is overridden, it still calls the overridden method.

4.4 anonymous implementation class of interface

There's nothing new about this.

Anonymity is also used when passing as a parameter. Look at the following example.

// Define the Animal interface
public interface Animal {
​
    // Define the speak abstract method
    public void speak();
}
​
@Test
public void test1(){
    testFunc(new Animal() {
        @Override
        public void speak() {
            System.out.println("Anonymous implementation class");
        }
    });
}
private void testFunc(Animal ani){
    ani.speak();
}

The above code is no different from the implementation of anonymous classes. They are generally used to pass parameters as methods. An interface is a new interface name, plus a pair of braces. In the braces, all the abstract methods of the interface are implemented. The essence of implementation is to rewrite all the abstract methods.

Compare the anonymous subclasses of abstract classes:

// There is an abstract class Animal
public abstract class Animal {
    // Abstract method speak
    public abstract void speak();
}
​
@Test
public void test1(){
    // The parameter of testFunc passes an anonymous class
    testFunc(new Animal() {
        @Override
        public void speak() {
            System.out.println("Anonymous classes, using");
        }
    });
}
private void testFunc(Animal ani){
    ani.speak();
}

See, the difference is that one is an interface and the other is an abstract class. The functions that can be realized are the same.

Interfaces are derived from abstract classes. It belongs to a special abstract class.

5. Proxy mode (proxy)

Proxy mode: provides a proxy for other objects to control access to this object.

The above sentence is very abstract. You must not understand it or remember it. ha-ha

take it easy.

First look at the code of the template method:

public abstract class Animal {
	// Abstract method
    public abstract void speak();
    
    // practical problem 
    public void spendTime(){
        long start = System.currentTimeMillis();
        speak();
        long end = System.currentTimeMillis();
        System.out.println("Cost:"+ (end - start)+"Such a long time!");
    }
}
// A non Abstract subclass
public class Dog extends Animal{
    public String type = "Dog";

    @Override
    public void speak(){
        System.out.println(this.type);
    }
}

// use
@Test
public void test1(){
    Animal dog = new Dog();
    testFunc(dog);
}
private void testFunc(Animal ani){
    ani.spendTime();
}

This pattern is that we add a little logic to the abstract method. In fact, you still need to call this abstract method.

Let's look at the code of the code pattern: here is the static proxy. Dynamic agents require reflective knowledge. I'll add it then.

// Define an interface with an abstract method.
public interface NetWork {
    // browse abstract method
    void browse();
}
// Define the proxy class, which is the implementation class of the interface
public class ServerImpl implements NetWork {

    @Override
    public void browse() {
        System.out.println("Server Implementation class implementation browse method");
    }
}
// Define the proxy class, which is also the implementation class of the interface
public class ProxyServer implements NetWork {
    // Variables of interface type must receive the implementation class of the interface, because the interface cannot instantiate objects
    private NetWork work;

    @Override
    public void browse() {
        System.out.println("Proxy class implementation method");
        check();
        this.work.browse();
    }
    // Inspection method
    public void check() {
        System.out.println("Inspection method");
    }

    public ProxyServer(NetWork work){
        this.work = work;
    }
}

// Test use
@Test
public void test1(){
    // new is the proxy class, and the parameters passed are the proxied class object
    ProxyServer proxyServer = new ProxyServer(new ServerImpl());
    // The method of the agent is executed.
    proxyServer.browse();
}

In the above code, there is a NetWork interface with a browse method. The proxy class ServerImpl must implement this method because it really works.

The proxy class ProxyServer is also a common implementation class of NetWork. You must also implement the browse method. It's just that he achieved something different. He rewrites the logic of browse by executing his own check method internally. Then the browse of the proxy class is executed.

@Override
public void browse() {
    System.out.println("Proxy class implementation method");
    check();
    this.work.browse();
}

Specifically, an object is received in the constructor in a polymorphic way, that is, the formal parameter is an interface type. Is a formal parameter of interface type, which can receive objects of any implementation class. Including himself. But if he can't really pass on himself, it will be a dead cycle. The received object is saved in the class property work.

Then, when re browsing, first execute the logic check to be added, and then call the browse method of the received object. Just like you entrust others to buy a house for you, when others buy a house, they increase the logic of house viewing and bargaining, and then ask you to pay yourself, and then he may continue to go through other procedures.

In the test, we can see that new is a proxy class object and passes an anonymous object of the proxy class. You can also pass ordinary famous objects.

Then the browse method of the proxy class is executed. It looks like the proxy class is working. In fact, the work done by the agent class includes the work you want to do.

And the previous template methods have realized the addition of deterministic logic on the basis of uncertain implementation.

Template methods are done directly in abstract classes, because abstract classes can have non abstract methods. But the interface is not allowed. So you can only do it in one implementation class. This implementation class is the proxy class.

Let's look at another proxy pattern based on abstract classes:

// Abstract class Animal
public abstract class Animal {
	// Abstract method speak
    public abstract void speak();
}
// Subclass dog inherits Animal
public class Dog extends Animal{
    public String type = "Dog";

    @Override
    public void speak(){
        System.out.println(this.type);
    }
}
// Subclass proxy class inherits Animal
public class AbstractClassProxy extends Animal{

    private final Animal ani;

    @Override
    public void speak() {
        long start = System.currentTimeMillis();
        ani.speak();
        long end = System.currentTimeMillis();
        System.out.println("Cost:"+ (end - start)+"Such a long time!");
    }

    AbstractClassProxy(Animal ani){
        this.ani = ani;
    }
}

// Test use
 @Test
public void test1(){
    AbstractClassProxy proxy = new AbstractClassProxy(new Dog());
    proxy.speak();
}

It is also possible to implement the proxy pattern with abstract classes. But it always feels a little awkward.

Because the subclasses of Animal class should be animals, it's strange to have an AbstractClassProxy here. Because AbstractClassProxy is not an Animal. It is generally believed that there should be a relationship between classes and subclasses. That is, the subclass belongs to the parent class. Not like here.

For such irrelevant inheritance, it is best to use interfaces. Because the interface is not called inheritance, it is called implementation instead. There is no such is a relationship. Or it makes up for the relationship other than the is a relationship.

6. Factory mode

When there is no factory, the creator and caller are together.

public interface Car {
    // run method
    void run();
}
public class AudiImpl implements Car {
    @Override
    public void run() {
        System.out.println("Audi run");
    }
}
public class BydImpl implements Car {
    @Override
    public void run() {
        System.out.println("byd Running");
    }
}
public class TestFunc {

    @Test
    void test1(){
        AudiImpl audi = new AudiImpl();
        BydImpl byd = new BydImpl();
        audi.run();
        byd.run();
    }
}

As in the proxy above, create audi with byd and their calls together. This is normal usage.

If you separate the creation of objects from object calls, it is the factory pattern.

6.1 factory method mode

Add a factory interface with an abstract method

public interface CarFactory {
    // Get Car
    Car getCar();
}

Now provide concrete implementation classes. To create different objects.

public class AudiFactoryImpl implements CarFactory {

    // Note that the return value of the overriding method can be the return value itself or a subclass of the interface definition
    // There is no problem writing Car directly as the return value here
    @Override
    public AudiImpl getCar() {
        return new AudiImpl();
    }
}
public class BydFactoryImpl implements CarFactory {
	
	// Here is to keep the original return value
    @Override
    public Car getCar() {
        return new BydImpl();
    }
}

use:

AudiImpl audi = new AudiFactoryImpl().getCar();
Car byd = (BydImpl)new BydFactoryImpl().getCar();

This is not the most perfect, because without adding a bike, you need to add a specific factory implementation class. When you learn reflection, you can break through this limitation.

6.2 abstract factory mode

This is more complex than the factory method pattern in creating objects.

The intention is to provide an interface to the client to create product objects in multiple product families.

The specific explanation will be explained in the design model column.

7. Inner class

A class is declared inside another class. This is different from writing multiple classes in the same file.

Writing inside means writing in braces of a class definition. The outer class is called the outer class, and the inner class is the inner class.

Why did this happen?

When we define attributes, simple attributes can not meet our needs. Complex data types are required.

Complex data types are classes.

In fact, it's OK to put internal classes outside. It is placed internally because these two classes are closely related.

public class InnerClassDemo {

    private InnerC inner;

    // Ordinary member inner class
    class InnerC {

    }
    // Static member inner class
    static class StaticInnerC{
        
    }
}

Look at the above code, which defines two member inner classes, one static and one non static. You can also define local inner classes.

public class InnerClassDemo {

    private InnerC inner;

    // Ordinary member inner class
    class InnerC {

    }
    // Static member inner class
    public static class StaticInnerC{

    }
    public void method() {
        // Local inner class
        class LocalInnerC{

        }
    }
    {   // Code block inner classes are also local inner classes
        class CodeBlockInnerC {

        }
    }
}

Most commonly used are member inner classes.

Analyze member internal classes from two aspects:

  • As a member of a class: it can be modified by permission, static, final and abstract.

Permissions in 4 can be modified. Note that external classes can only be public or default

static and final modifications are consistent with attributes and methods.

  • As a class: it has the characteristics of all classes.

Examples of inner classes:

For example: Integer There is one in the packaging category IntegerCache Internal class.

7.1 how to instantiate member inner classes?

If you want to instantiate a member's inner class externally, the inner class must be accessible externally. That is, the permission of the class must be public and static

InnerClassDemo.StaticInnerC staticInnerC = new InnerClassDemo.StaticInnerC();

For non static internal classes, you need to instantiate the external class object first, and then new it. Attention is the object New inner class name

InnerClassDemo innerClassDemo = new InnerClassDemo();
InnerClassDemo.InnerC innerC = innerClassDemo.new InnerC();

7.2 how to distinguish the structure of calling external classes in member internal classes?

public class InnerClassDemo {

    private InnerC inner;

    private String name = "External class";

    // Ordinary member inner class
    public class InnerC {
        private String name = "General inner class";
    }
    // Static member inner class
    public static class StaticInnerC{
        private String name = "Static inner class";
    }
    
    public void method() {
        // Local inner class
        class LocalInnerC{
            private String name = "Method local inner class";
        }
    }
    {   // Code block inner classes are also local inner classes
        class CodeBlockInnerC {
            private String name = "Code block local inner class";
        }
    }
}

The above shows that all classes have the name attribute of the same name to see how to distinguish calls

public class InnerClassDemo {

    private InnerC inner;

    private String name = "External class";

    // Ordinary member inner class
    public class InnerC {

        private String name = "General inner class";
        public void test(){
            // Call the attribute name of the external class
            System.out.println(InnerClassDemo.this.name);
        }
        // test
        public void test(String name){
            System.out.println(name); // Call method parameters
            System.out.println(this.name); // Call the properties of this class
            System.out.println(InnerClassDemo.this.name); // Properties of external classes
        }
    }
    // Static member inner class
    public static class StaticInnerC{
        private String name = "Static inner class";
    }

    public void method() {
        // Local inner class
        class LocalInnerC{
            private String name = "Method local inner class";
        }
    }
    {   // Code block inner classes are also local inner classes
        class CodeBlockInnerC {
            private String name = "Code block local inner class";
        }
    }
}

Tested in the ordinary back class. The usage of this remains the same. Non static structures still cannot call static structures.

The internal class calls the external class attribute with the external class name this. Property name

7.3 use of local internal classes

Local inner class

public void method() {
        // Local inner class
        class LocalInnerC{
            private String name = "Method local inner class";
        }
    }

The above method of use is rare. It is usually used when you need to obtain an object. See the call below

// Gets a class object that implements the Comparable interface
    // Mode 1:
    public Comparable getComparable1(){

        // Create a class of Comparable interface, which is a local internal class
        class MyComparable implements Comparable{

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
    }
    // Mode 2:
    public Comparable getComparable2(){

        // Anonymous implementation class, which is also an internal class
        return new Comparable(){

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }

You will find that anonymous classes can replace famous classes, which are used internally once. So mode 2 is more common.

Keywords: Java IDEA

Added by kuma on Fri, 31 Dec 2021 01:18:11 +0200