define

Classes defined within a class are called inner classes.

role

1. Inner classes can hide implementation well; Private and protected privileges are not allowed for non-inner classes, but inner classes are allowed. 2. 3. The inner class has all the access rights of the outer class. 4. Avoid overwriting problems when the parent class and interface have the same method name.

parsing

1. Inner classes can hide implementation well;

Since the external class is not allowed to be defined as private or protected, if we want to hide some of our implementation details, we can use the inner class to do so. For example, payment is a core function, which needs to be hidden as much as possible. The caller only needs to be able to use it, as follows:

public interface IPay{  
    void pay();  
}  
  
public class Payer1 {  

    private class PayImpl implements IPay{  
      
        public void pay() {  
          System.out.println("pay ing...");
        }  
    }  
  
    public IPay startPay() {  
        return new PayImpl();  
    }  
}  
  

class TestPay {
    public static void main(String[] args) {  
        Payer1 pm = new Payer1();  
        IPay p = pm.startPay();  
        p.pay();  
    }  
}  
Copy the code

The PayImpl above is defined in the inner class and controls access with the private modifier. In the later main method, we operate directly through the ipay.pay () method, and external callers don’t even see the name of the implementation class, thus hiding implementation details as much as possible and demonstrating Java encapsulation.

2. Inner classes can implement multiple inheritance;

In the real world, there are multiple inheritance relationships. For example, a child inherits genes from both his father and his mother, his father can work, his mother can dance, and the child inherits all of these genes from his parents. How do you represent that in Java code? Since a class in Java supports only single inheritance and multiple implementations, it doesn’t seem reasonable to define parent and parent using an interface for this scenario, so inner classes come into play here:

public class father {
  void work(){...}
}

public class mother{
  void dancing(){...}
}

public class Child {

  public static void main(String args[])
   {
       Child child=new Child ();
       child.work();
       child.dancing();
   }


   public void work(){
    InnerChild1 child1 = new InnerChild1 ();
    child1.work();
    }

   public void dancing(){
    InnerChild2 child2 = new InnerChild2 ();
    child2.dancing();
    }



    private class InnerChild1 extends father{

        void work() {
          super.work();
        }
    }

    private class InnerChild2 extends mother{

        void dancing() {
          super.dancing();
        }
    }
}
Copy the code

In this way, the children inherit their parents’ excellent genes, which can be described as a double fragrance of talent.

3. The inner class has all the access rights of the outer class

Because a non-static inner class holds references to an external class, it can access all properties and methods of the external class, which provides great flexibility in program design. Modify the first code slightly:

public interface IPay{  
    void pay();  
}  
  
public class Payer1 {  
   private double money;

    private class PayImpl implements IPay{  
      
        public void pay() {  
          money --;
          System.out.println("pay ing...");
        }  
    }  
  
    public IPay startPay() {  
        return new PayImpl();  
    }  
}  
  

class TestPay {
    public static void main(String[] args) {  
        Payer1 pm = new Payer1 ();  
        IPay p = pm.startPay();  
        p.pay();  
    }  
}  
Copy the code

We added a new money field decorated with private in the outer class, and then changed the value of that field when the inner class PayImpl called the Pay method so that the outer class could be accessed directly from the inner class.

4. Avoid overwriting problems when the parent class and interface have the same method name

Imagine if your class wanted to inherit from a class and implement an interface, but you found two methods with the same name in your inherited class and interface? How do you tell them apart? You might say, why don’t I change it to a different name and be done with it? What’s the big deal? You can do that if you can change both the parent class and the interface, but is there a way to fix the problem without changing it, or if you don’t have a chance to change it at all? For example, if they are a third party SDK that you introduced, what should you do? This is where we need to implement the inner class:

public class Payer{ void pay(){ System.out.println("Payer implement..." ); } } public interface IPay{ void pay(); } // In the previous section, the Payer class and IPay interface have the same method pay(), and then we have the following implementation method:  public class Payer1 extends Payer implements IPay{ @override public void pay() { System.out.println("pay ing..." ); }} // Pay () is a method that overwrites Payer. Again, IPay is the way it is here. How can I switch to Payer's method here? Obviously it's hard to tell the difference. We can easily solve this problem by using inner classes. Public class Payer1 extends Payer {private class InnerPayer implements IPay {public void pay() { Payer1.this.pay(); } } IPay startPay() { return new InnerPayer (); } } class TestPay { public static void main(String[] args) { Payer1 pm = new Payer1 (); IPay p = pm.startPay(); p.pay(); }}Copy the code

This perfectly solves the problem of overwriting the method of the same name.